Wstawki asemblerowe.
Rozkazy asemblera jako linie programu języka BASCOM BASIC.
Instrukcje mnemoniczne są rozpoznawane przez kompilator automatycznie. Jedynym wyjątkiem jest instrukcja SWAP, która także występuje w składni języka BASCOM BASIC. Aby kompilator wiedział o tym, że używany jest skrót mnemoniczny, należy ją poprzedzić znakiem wykrzyknika (!). Można go także umieszczać przed innymi instrukcjami asemblera. Uwaga! W rozkazach rejestr ACC jest oznaczony jako A (z wyłączeniem operacji na bitach!).
np.: Mov A,#10 'ok.
Mov Acc,#10 'także ok., choć zajmie o 1 bajt więcej
Setb Acc.0 'ok.
Setb A.0 'BŁĘDNIE!
Można także łączyć program w języku asemblera za pomocą dyrektywy $INCLUDE <plik.ASM>. Ma to tą zaletę, że wstawki w asemblerze mogą zostać ukryte. Asembler pracuje w oparciu o standardowe mnemoniki zdefiniowane przez Intel-a.
Dostęp do etykiet z poziomu asemblera.
Każda etykieta pojawiająca się w programie języka BASCOM BASIC jest zmieniana w taki sposób, że przed jej nazwą dodawana jest kropka.
np.: Goto Test
Test:
zostanie przetłumaczony na kod:
LJMP .Test
.Test:
Gdy etykiety używane są tylko we fragmencie w asemblerze, można je poprzedzić znakiem wykrzyknika. Nie będą one wtedy zamieniane na te z kropką:
np.: Jb P1.0, Test ;brak kropki
!test: ;określa etykietę w ASM
Można także samemu umieścić kropkę przed nazwą etykiety. Inną godną polecenia alternatywą jest umieszczenie kodu programu w asemblerze stosując dyrektywy $ASM..$END ASM.
np.: $asm
Mov A , #1
Test:
Sjmp Test
$end asm
Sposób przechowywania zmiennych.
Zmienne typu Bit są umieszczone w bajtach. Zajmują one adresy 20h -2Fh, gdzie można umieścić 16 * 8 = 128 zmiennych. Żeby mieć dostęp do nich można używać:
np.: Dim var As Bit 'dim variable
Setb {var} ;ustaw bit
Clr {var} ;skasuj bit
Print var ;wydrukuj
End
lub też normalnych instrukcji języka BASCOM BASIC: SET oraz RESET, które robią dokładnie to samo.
Zmienne typu Byte umieszczane są tuż za zmiennymi bitowymi. Począwszy od adresu 20h + (ilość bajtów zajmowanych przez zmienne bitowe). Zmienne typu Integer/Word są zapisywane według standardu Intela, najpierw bajt LSB, potem MSB. To samo dotyczy zmiennych typu Long - które zajmują 4 bajty. Uwaga! Jest to inny sposób zapisu niż stosowany w BASCOM LT, w którym najpierw zapisywany jest bajt MSB. (standard Motoroli).Można uzyskać dostęp do zmiennej umieszczając jej nazwę w nawiasach klamrowych { }. By mieć dostęp do bajtu MSB zmiennych Integer/Word, należy użyć formy: {zmienna+1}, dla zmiennych typu Long należy dodać trzy: {zmienna + 3}.
np.: Dim t As Byte , c As Integer
Clr A ;zerowanie rejestru ACC
Mov {t} , A ;zerowanie zmiennej t
Inc {t} ;t = t + 1
Mov {c} , {t} ;c = t
Mov {c+0}, {t} ;LSB zmiennej C = t (nie trzeba podawać +0)
Mov {c+1}, {t} ;MSB zmiennej C = t
Mov {c},#10 ;przypisanie wartości
Można zmieniać także zawartość rejestrów w przestrzeni SFR z poziomu języka BASIC.
np.: P1 = 12 'to jest chyba jasne
Acc = 5 'to jest ok.
B = 3 'B to także rejestr SFR
Mul AB 'Acc = Acc * B
Print B ; Acc
Zmienne w pamięci XRAM są umieszczane podobnie. Zmienne typu String zapisywane są w kolejnych bajtach i zakończone bajtem o wartości zero.
np.: $ramstart = 0
Dim s As String * 10 'rezerwacja 11 bajtów (10 + 1 na znak końca)
s = "abcde" 'jakiś ciąg znaków
komórka ram 0 = a (pierwsza komórka pamięci)
komórka ram 1 = b
komórka ram 2 = c komórka ram 3 = d
komórka ram 4 = e komórka ram 5 = #0
Zmienne umieszczone w pamięci XRAM są dostępne w trochę inny sposób.
np.: Dim T As XRAM Byte
Mov DPTR,#{T} ;adres zmiennej T do wskaźnika
Mov A,#65 ;umieść “A” w Acc
Movx @DPTR,A ;wpisz do pamięci
Print T ;wydrukuj z BASIC-a
Dim T1 As XRAM Integer
Mov DPTR,#{T1} ;ustaw wskaźnik
Mov A,#65 ;wpisz “A” w Acc (LSB)
Movx @DPTR,A ;wpisz do pamięci
Inc DPTR ;przesuń wskaźnik
Mov A,#1 ;1 do MSB
Movx @DPTR,A ;wpisz do pamięci
Print T1 ;wydrukuj z BASIC-a
Procedury pomocnicze.
Istnieją dwie nowe procedury pomocnicze, użyteczne podczas tworzenia kodu w asemblerze. Są to: PLACEVALUE zmienna , SFR i PLACEADRES zmienna , SFR (PLACEVALUE przepisuje wartość zmiennej do określonego rejestru w przestrzeni SFR).
np.: Placevalue 1 , ACC
wygeneruje kod:
Mov A,#1
np.: Dim x As Byte
Placevalue x , R0
wygeneruje kod:
Mov A, h'3A ;oczywiście tylko w tym przykładzie
Instrukcja może być przydatna w połączeniu ze zmiennymi będącymi tablicami.
np.: Placevalue a(x), RO
wygeneruje kod:
Mov R0,#h'3A
Mov A,@R0
Rl A
Add A,#h'1F
Mov R0,A
Mov A,@R0
Powyższe fragmenty kodu są przykładowe. Wygenerowany kod może odbiegać od tego schematu, gdyż w programie mogą być użyte innego typu zmienne. Można przypisać tylko jeden SFR za pomocą instrukcji PLACEVALUE. Z pomocą przychodzi jednak instrukcja PLACEADRES, która umieszcza adres zmiennej w pamięci do podanego rejestru.
np.: Placeadres ar(x) , ACC
Placeadres z , R0
Jeśli używane są zmienne, które umieszczono w pamięci XRAM, nie jest potrzebne podawanie rejestru gdzie adres ma trafić, gdyż używany jest zawsze rejestr DPTR.
np.: Dim X As Xram Integer
Placeadres x , DPTR 'lub PLACEADRES x
wygeneruje kod:
Mov DPTR,#2
lub dla tablic::
Placeadres ar(x)
Mov DPTR,#2
Mov R0,#h'37
Mov A,@R0
Mov R2,A
Inc R0
Mov A,@R0
Mov R3,A
Mov R1,#1
Acall _AddIndex
Oczywiście to tylko przykłady, rzeczywista postać kodu zależy od typu i miejsca gdzie umieszczono zmienną (IRAM, XRAM).
Notacja szesnastkowa i binarna.
Aby używać zapisu liczb w postaci szesnastkowej, to można to zrobić w ten sposób:
np.: Mov A,#h'AA
Jest to dość zawiły sposób, lecz można używać także notacji przyjętej przez BASIC:
np.: Mov A,#&HAA
W instrukcjach asemblera można także używać zapisu binarnego.
np.: Mov A,#&B10001000
Skoki z wykorzystaniem offsetu.
Można określić o ile bajtów do przodu lub tyłu ma skoczyć program, bez używania etykiet.
np.: Jb P1.0 , *+12 ;skok do przodu
Jb P1.0 , *-12 ;skok do tyłu
Jnb P1.0 , *+0 ;pętla powtarzana dopóki P1.0 pozostanie w stanie wysokim
Rozwiązanie to jest dostępne także dla instrukcji, które zwykle skaczą pod podaną etykietę: SJMP, LJMP, DJNZ itd.
Wewnętrzny bufor przy konwersji liczb na ciąg znaków.
Podczas drukowania liczb instrukcją PRINT, czy konwersji liczb za pomocą funkcji STR() lub VAL(), używany jest wewnętrzny bufor o wielkości 16 bajtów. Zaletą tego rozwiązania jest zmniejszenie zapotrzebowania na stos, lecz wadą jest użycie zawsze 16 bajtów z puli pamięci RAM. Oczywiście, jest on dostępny dla programu i posiada nazwę: ___TMP_S1. Jeśli więc w programie będzie potrzebny tymczasowy ciąg znaków można go użyć. Uwaga! Bufor jest dostępny tylko, gdy w programie występują powyższe instrukcje!
np.: Dim s As Single
s = 1.1
Print s 'używany jest bufor
___TMP_S1 = "Użyjemy go tu"
Print ___TMP_S1
Komentarze.
Jako znaku rozpoczynającego komentarz można używać znaku ; lub też apostrofu - jak w programie w języku BASCOM BASIC:
np.: Mov A,#1 ;komentarz
Mov A,#2 'komentarz