1. Dyrektywy asemblerowe

1. Dyrektywy asemblerowe Asembler A51 ma kilka dyrektyw, które pozwalają na definiowanie symboli, wartości, rezerwację i inicjalizację pamięci oraz ...
2 downloads 0 Views 598KB Size
1.

Dyrektywy asemblerowe

Asembler A51 ma kilka dyrektyw, które pozwalają na definiowanie symboli, wartości, rezerwację i inicjalizację pamięci oraz sterowanie umiejscowieniem kodu programu. Dyrektywy nie powinny być mylone z instrukcjami. Nie wytwarzają one wykonywalnego kodu i, za wyjątkiem dyrektyw DB i DW, oraz nie wpływają bezpośrednio na zawartość kodu programu. Poniższa tabela pokazuje najczęściej wykorzystywane dyrektywy asemblerowe zaimplementowane w omawianym asemblerze firmy Keil. Dyrektywa CSEG BSEG DSEG ISEG XSEG

EQU SET BIT CODE DATA

IDATA

XDATA

DB DW DBIT DS

ORG USING

NAME END

Format

Opis Segmenty CSEG [AT adres_absolutny] Definicja segmentu absolutnego w pamięci kodu BSEG [AT adres_absolutny] Definicja segmentu absolutnego w pamięci danych adresowanej bitowo DSEG [AT adres_absolutny] Definicja segmentu absolutnego w wewnętrznej pamięci danych adresowanej bezpośrednio ISEG [AT adres_absolutny] Definicja segmentu absolutnego w wewnętrznej pamięci danych adresowanej pośrednio XSEG [AT adres_absolutny] Definicja segmentu absolutnego w zewnętrznej pamięci danych Definicje symboli symbol EQU wyrażenie Trwałe przypisanie wartości symbolowi symbol SET wyrażenie Czasowe przypisanie wartości symbolowi symbol BIT adres_bitu Definicja adresu bitu w bitowej przestrzeni danych symbol CODE adres_kodu Przypisanie symbolowi określonego adresu w przestrzeni pamięci kodu symbol DATA adres_danej Przypisanie symbolowi określonego adresu z wewnętrznej przestrzeni danych adresowanej bezpośrednio symbol IDATA adres_danej Przypisanie symbolowi określonego adresu z wewnętrznej przestrzeni danych adresowanej pośrednio symbol XDATA adres_danej Przypisanie symbolowi określonego adresu z zewnętrznej przestrzeni danych Inicjalizacja pamięci kodu [etykieta:] DB wyrażenie [,wyrażenie,...] Tworzy listę wartości, każda o rozmiarze bajta [etykieta:] DW wyrażenie [,wyrażenie,...] Tworzy listę wartości, każda o rozmiarze słowa Rezerwacja pamięci danych [etykieta:] DBIT wyrażenie Rezerwuje w pamięci określoną wyrażeniem liczbę bitów [etykieta:] DS wyrażenie Rezerwuje w pamięci określoną wyrażeniem liczbę bajtów Przełączanie adresów ORG wyrażenie Określa umiejscowienie bieżącego segmentu USING wyrażenie Określa predefiniowany adres rejestru symbolicznego i rezerwuje przestrzeń dla określonego banku rejestrów Inne NAME nazwa_modułu Określa nazwę bieżącego modułu END Wskazuje koniec programu

1

2.

Dyrektywy związane z segmentami

Segment jest blokiem pamięci kodu lub danych, który tworzy asembler z kodu lub danych znajdujących się w pliku źródłowym. Użycie segmentów w module źródłowym jest zależne od złożoności aplikacji. Małe aplikacje wymagają mniejszej pamięci i są zwykle mniej złożone niż duże, wielomodułowe aplikacje. Mikrokontroler MCS-51 ma kilka różnych, specyficznych dla siebie, przestrzeni pamięci, jak:  pamięć kodu programu,  wewnętrzna pamięć danych adresowana bitowo, bezpośrednio lub pośrednio,  zewnętrzna pamięć danych. Segmenty są więc używane do umiejscowienia kodu programu, stałych i zmiennych w tych przestrzeniach. 2.1

Licznik położenia

Podczas swojej pracy program asemblujący (asembler) przyporządkowuje każdemu segmentowi tzw. licznik położenia, który jest wskaźnikiem adresu w przestrzeni aktywnego segmentu. Adres ten jest adresem względnym dla segmentu relokowalnego lub adresem bezwzględnym (rzeczywistym) dla segmentu absolutnego. Kiedy dany segment jest po raz pierwszy aktywowany, licznik położenia jest ustawiany na 0. Jego wartość jest zmieniana po przeanalizowaniu danej instrukcji o wartość związaną z jej implementacją w danym segmencie. Dyrektywy inicjalizacji i rezerwacji pamięci (np. DS, DB lub DBIT) zmieniają wartość licznika położenia po przydzieleniu pamięci przez tą dyrektywę. Dyrektywa ORG ustala nową wartość dla licznika położenia. Jeśli nastąpi zmiana aktywnego segment na inny, a potem powrót do niego, to licznik położenia przyjmuje taką wartość, jaką miał ostatnio przy korzystaniu z danego segmentu. Zawsze, kiedy asembler napotka etykietę, przypisuje jej bieżącą wartość licznika położenia i typ bieżącego segmentu dla tej etykiety. Znak dolara ($) sygnalizuje wartość licznika położenia w aktywnym segmencie. Kiedy używa się symbolu $, należy pamiętać, że jego wartość zmienia się z każdą instrukcją, lecz tylko po tym, jak instrukcja ta zostanie całkowicie zanalizowana przez asembler. Jeśli użyje się znaku $ w miejscu operandu instrukcji lub dyrektywy, to reprezentuje on wtedy adres pierwszego bajta tej instrukcji. 2.2

Segmenty bezwzględne (absolutne)

Segmenty absolutne rezydują w określonym typie pamięci pod stałym adresem ustalanym przez programistę na poziomie pisania kodu programu. Są tworzone przy użyciu dyrektyw: CSEG, BSEG, DSEG, ISEG i XSEG. Wymienione dyrektywy umożliwiają umieszczanie kodu i danych lub rezerwację przestrzeni pamięci pod określonym adresem. Segmenty absolutne są używane wtedy, gdy istnieje konieczność posiadania dostępu do stałego miejsca w pamięci lub umieszczenia kodu lub stałych od określonego adresu. Po resecie mikrokontroler rozpoczyna wykonywanie programu od adresu 0. Jeśli właściwy program nie zaczyna się od tego adresu, to pod nim musi być umieszczona co najmniej jedna instrukcja, która przekieruje wykonywanie programu pod właściwy adres. Aby wymusić umieszczenie kodu programu od innego adresu należy wykorzystać segmenty absolutne. Poniższy przykład przedstawia fragment programu, gdzie wymuszono w początkowej fazie jego wykonywania, skok do podprogramu inicjalizującego, który jest umieszczony w dalszej części pamięci kodu. CSEG AT 0 RESET_VECT: LJMP STARTUP ... Kod programu, który został umieszczony od adresu 0000H za pomocą dyrektywy CSEG AT 0 wykonuje operację skoku pod etykietę STARTUP.

BSEG, CSEG, DSEG, ISEG, XSEG Dyrektywy BSEG, CSEG, DSEG, ISEG, XSEG określają adres bezwzględny w odpowiednim segmencie programu, od którego będą umieszczane instrukcje występujące po tej dyrektywie. Adres segmentu jest więc ustalany przez programistę już w chwili pisania programu. Omawiane dyrektywy mają następujący format: BSEG CSEG DSEG ISEG XSEG

AT AT AT AT AT

adres adres adres adres adres

;definiuje ;definiuje ;definiuje ;definiuje ;definiuje

bezwzględny bezwzględny bezwzględny bezwzględny bezwzględny

2

adres adres adres adres adres

w w w w w

segmencie segmencie segmencie segmencie segmencie

BIT CODE DATA XDATA IDATA

adres

jest bezwzględnym adresem bazowym, od którego będzie rozpoczynał się segment. Adres nie może zawierać odniesień w przód i musi być wyrażeniem, które po obliczeniu daje konkretną wartość.

Dyrektywy BSEG, CSEG, DSEG, ISEG, XSEG określają segmenty absolutne odpowiednio w przestrzeni: danych adresowanych bitowo, kodu, wewnętrznej przestrzeni danych adresowanych bezpośrednio, wewnętrznej przestrzeni danych adresowanych pośrednio, zewnętrznej przestrzeni danych. Użycie jednej z wymienionych dyrektyw powoduje, że program asemblujący kończy wcześniejszy segment, jeśli taki był, w danej klasie pamięci i tworzy nowy segment absolutny w wyspecyfikowanej klasie, rozpoczynając go od adresu podanego w instrukcji. Jeśli w instrukcji nie zostanie określony adres, to jest kontynuowany ostatni bezwzględny segment danego typu. Jeśli wcześniej nie został określony żaden segment bezwzględny tego typu, a w instrukcji nie określono adresu, to nowy segment jest tworzony od adresu 0. Przykłady: DEC_FLAGA: INC_FLAGA: PARZ_TAB:

BSEG AT 20h DBIT 1 DBIT 1

;absolutny segment bitowy od 20h ;bit o adresie absolutnym

CSEG AT 100h DB 00h DB 01h DB 00h DB 01h

;absolutny segment kodu od 100h ;parzystość dla 00h ;01h ;02h ;03h

DB 01h DB 00h

;FEh ;FFh

DSEG AT 40h DS 2 DS 4

;absolutny segment danych od 40h ;słowo danych o adresie absolutnym

ISEG AT 80h

;absolutny segment danych w pamięci ;adresowanej pośrednio od 80h

... ... ...

TMP_A: TMP_B:

TMP_IA: TMP_IB:

DS 2 DS 4 XSEG AT 1000h

NAZWA1: NAZWA2: WERSJA:

DS 25 DS 25 DS 25

NOWA_FLAGA:

BSEG DBIT 1

2.3

;absolutny segment w zewnętrznej ;pamięci danych od 1000h ;dana w pamięci zewnętrznej o adresie ;absolutnym ;dalsza część absolutnego ;segmentu bitowego

Segment domyślny

Na początku procesu asemblacji pliku źródłowego, program asemblujący domyślnie przyjmuje, że wybrany został segment kodu. Dodatkowo licznik położenia przypisany do tego segmentu inicjowany jest adresem 0000H. Umożliwia to stworzenie prostego programu bez konieczności określania segmentów relokowalnych i/lub absolutnych.

3.

Definicje symboli

Dyrektywy definiujące symbole umożliwiają tworzenie symboli, które mogą być używane do reprezentacji rejestrów, liczb i adresów. Symbole definiowane przez te dyrektywy nie mogą być wcześniej zdefiniowane i nie mogą być definiowane ponownie. Wyjątkiem od tych reguł jest dyrektywa SET.

3

EQU, SET Dyrektywy EQU i SET przyporządkowują wartości numeryczne lub symbole rejestrów do wyspecyfikowanych nazw symbolicznych. Symbole zdefiniowane za pomocą dyrektywy EQU nie mogą być wcześniej zdefiniowane, a także nie mogą być później redefiniowane. Dyrektywa SET umożliwia późniejszą redefinicję symbolu. Instrukcje wymagające dyrektyw EQU i SET maja następujący format: symbol symbol symbol symbol symbol

wyrażenie rejestr

EQU EQU SET SET

wyrażenie rejestr wyrażenie rejestr

nazwa symboliczna do zdefiniowania. Wyrażenie lub rejestr wyspecyfikowany w dyrektywach EQU lub SET będzie wstawiany przy każdym wystąpieniu symbolu w bieżącym programie asemblerowym. wyrażenie numeryczne, które nie zawiera odniesień w przód lub jest prostym wyrażeniem relokowalnym. jedna z nazw rejestrów, np.: A, R0, R1, R2, R3, R4, R5, R6 lub R7.

Symbole zdefiniowane za pomocą dyrektywy EQU lub SET mogą być użyte w operandach, wyrażeniach lub adresach. Natomiast symbole, które są zdefiniowane jako nazwy rejestrów, mogą być użyte wszędzie, gdzie dopuszczalne jest użycie rejestrów. Nie można użyć dyrektywy SET, jeśli symbol został wcześniej zdefiniowany za pomocą dyrektywy EQU i odwrotnie. Przykłady: GRANICA ROZMIAR SERIAL ACCU LICZNIK1 WARTOSC WARTOSC LICZNIK2 TEMP TEMP

EQU EQU EQU EQU EQU SET SET SET SET SET

1200 GRANICA – 200 + 'A' SBUF A R5 100 WARTOSC / 2 R1 LICZNIK2 WARTOSC * WARTOSC

BIT, CODE, DATA, IDATA, XDATA Dyrektywy BIT, CODE, DATA, IDATA, XDATA przyporządkowują danemu symbolowi adres w określonym typie pamięci. Symbole zdefiniowane za pomocą dyrektyw BIT, CODE, DATA, IDATA, XDATA nie mogą być zmieniane, jak również redefiniowane. Omawiane dyrektywy mają następujący format: symbol symbol symbol symbol symbol symbol adres_bit adres_code

BIT CODE DATA IDATA XDATA

adres_bit adres_code adres_data adres_idata adres_xdata

definiowana nazwa symboliczna. Może być używany w każdym miejscu, gdzie wymagany jest adres w pamięci wyspecyfikowanego typu. jest adresem bitu z wewnętrznej pamięci danych w przestrzeni o adresach z zakresu 20H .. 2FH adresowanej bitowo lub adresem bitu rejestru SFR adresowanego bitowo. jest adresem w pamięci kodu z zakresu 0000H .. FFFFH.

4

jest adresem rejestru SFR z zakresu adresów 80H .. FFH lub adresem z wewnętrznej pamięci danych z zakresu 0 .. 7FH. adres_idata jest adresem w wewnętrznej pamięci danych adresowanej pośrednio z zakresu 00H .. FFH. adres_xdata jest adresem w zewnętrznej pamięci danych z zakresu 0000H .. FFFFH. adres_data

Przykłady DATA_SEG

SEGMENT RSEG

BIT DATA_SEG

CTRL: ALARM SHUT ENABLE_FLAG DONE_FLAG RESTART INTVEC_0 INTVEC_1 INTVEC_2 SERBUF RESULT RESULT2 BUFFER BUF_LEN BUF_END

DS BIT BIT BIT BIT CODE CODE CODE CODE DATA DATA DATA IDATA EQU IDATA

XSEG1

SEGMENT RSEG

DTIM: TIME DATE

DS 6 XDATA DTIM + 0 XDATA DTIM + 3

4.

;segment relokowalny adresowany ;bitowo ;1–bajtowa zmienna (CTRL) ;bit w relokowalnym bajcie ;następny bit ;bezwzględny bit ;bezwzględny bit

1 CTRL.0 ALARM+1 60H 24H.2 00H RESTART + 3 RESTART + 0BH RESTART + 1BH SBUF ;redefinicja bufora SBUF 40H RESULT + 2 60H 20H BUFFER + BUF_LEN – 1 XDATA XSEG1

;rezerwuje 6–bajtów dla DTIM

Inicjalizacja pamięci

Dyrektywy inicjalizujące pamięć są używane do inicjalizacji pamięci kodu stałymi wartościami o rozmiarze jednego lub dwóch bajtów. Zapisywanie pamięci wspomnianymi stałymi odbywa się od miejsca wskazywanego przez bieżącą wartość licznika położenia w obecnie aktywnym segmencie.

DB Dyrektywa DB inicjalizuje pamięć wartościami, z których każda ma rozmiar jednego bajta. Omawiana dyrektywa ma następujący format: etykieta:

DB

wyrażenie, wyrażenie ...

jest symbolem, który określa adres inicjowanej pamięci. jest wartością o rozmiarze bajta. Każde wyrażenie może być symbolem, ciągiem znaków lub wyrażeniem. Dyrektywa DB może być umieszczana tylko wewnątrz segmentu kodu programu. Jeśli zostanie użyta w innym segmencie, program asemblujący wygeneruje informację o błędzie. etykieta wyrażenie

Przykłady: REQUEST: TABLE: ZERO: CASE_TAB: KODY_LED

DB DB DB DB DB

'WCISNIJ DOWOLNY KLAWISZ', 0 0,1,8,'A','0', LOW(TABLE),';' 0, '''' LOW(REQUEST), LOW(TABLE), LOW(ZERO) 23H ;kod zera

5

DB DB

3FH ... ... 0FAH

;kod jedynki ;kod dziewiątki

DW Dyrektywa DW inicjalizuje pamięć wartościami, z których każda ma rozmiar dwóch bajtów. Omawiana dyrektywa ma identyczny format, jak dyrektywa DB. etykieta:

DW

wyrażenie, wyrażenie ...

jest symbolem, który określa adres inicjowanej pamięci. jest wartością o rozmiarze dwóch bajtów. Każde wyrażenie może być symbolem, ciągiem znaków lub wyrażeniem. Dyrektywa DW może być umieszczana tylko wewnątrz segmentu kodu programu. Jeśli zostanie użyta w innym segmencie, program asemblujący wygeneruje informację o błędzie. etykieta wyrażenie

Przykłady: TABLE: CASE_TAB:

5.

DW DW DW

1234, 233AH, ‘QR’ CASE0, CASE1, CASE2, CASE3, CASE4 $

Rezerwacja pamięci

Dyrektywy rezerwacji pamięci są używane do rezerwacji przestrzeni jednostkami o rozmiarze: bajta, słowa lub bitu. Rezerwacja przestrzeni rozpoczyna się w punkcie wskazywanym przez bieżącą wartość licznika położenia w obecnie aktywnym segmencie.

DBIT Dyrektywa DBIT rezerwuje przestrzeń w segmencie danych adresowanych bitowo. Jej format jest następujący: etykieta

DBIT

wyrażenie

jest symbolem, który określa adres w rezerwowanej pamięci. Etykieta jest symbolem typu BIT i pobiera bieżącą wartość adresu oraz klasę pamięci aktywnego segmentu. Etykieta ta może być użyta wszędzie tam, gdzie dopuszczalne jest użycie segmentu tego typu. wyrażenie liczba rezerwowanych jednostek, każda o rozmiarze jednego bita Wyrażenie nie może zawierać odniesień w przód, symboli relokowalnych lub symboli zewnętrznych. Dyrektywa DBIT rezerwuje przestrzeń w segmencie adresowanym bitowo rozpoczynając od bieżącego adresu. Licznik położenia związany z segmentem bitowym jest zwiększana o wartość wyrażenie. Należy pamiętać, że licznik położenia dla segmentu bitowego odnosi się do bitów nie do bajtów. etykieta

Przykłady: ON_FLAG: OFF_FLAG:

DBIT DBIT

1 2

; rezerwuje fragment pamięci o rozmiarze 1 bita ; rezerwuje fragment pamięci o rozmiarze 2 bitów

UWAGA. Asembler firmy Keil jest asemblerem dwuprzebiegowym. W pierwszym przejściu, zbierane są wszystkie symbole oraz określana jest długość każdej instrukcji. W drugim przejściu, obliczane są wyrażenia z doniesieniami w tył oraz tworzony jest kod obiektów. Z tego powodu wyrażenia używane w dyrektywie DBIT nie mogą zawierać odniesień w tył.

6

DS Dyrektywa DS rezerwuje określoną liczbę bajtów w przestrzeni pamięci danych. Jej format ma następującą postać: etykieta:

DS

wyrażenie

jest symbolem, który określa adres rezerwowanej pamięci. Etykieta pobiera bieżącą wartość adresu i klasę pamięci aktywnego segmentu. Etykieta ta może być użyta tam, gdzie użycie segmentu tego typu jest dopuszczalne. wyrażenie jest liczbą rezerwowanych jednostek, każda o rozmiarze jednego bajta. Wyrażenie nie może zawierać odniesień w przód, symboli relokowalnych lub zewnętrznych symboli. Dyrektywa DS rezerwuje przestrzeń w bieżącym segmencie rozpoczynając od bieżącego adresu. Jest on następnie zwiększany o wartość wyrażenie. Suma licznika położenia i wartości wyrażenie nie może przekroczyć granicznego rozmiaru dostępnej przestrzeni adresowej w danym segmencie. etykieta

Przykłady: GAP: TIME:

DS DS DS

(($ + 12) AND 0FFF0H) – $ 20 8

Uwaga zawarta w opisie dyrektywy DBIT dotyczy również dyrektywy DS.

6.

Kontrolowanie adresów w segmentach

Poniższe dyrektywy umożliwiają sterowanie wartością licznika położenia lub symbolami rejestrów absolutnych.

ORG Dyrektywa ORG jest używana do zmiany wartości licznika położenia w obecnie aktywnym segmencie i ustalenia nowego adresu od którego będą umieszczane dalsze instrukcje. Omawiana dyrektywa ma następujący format: ORG

wyrażenie

musi być wyrażeniem absolutnym lub relokowalnym w prosty sposób bez odniesień w przód. Mogą być używane tylko adresy absolutne lub wartości symboliczne z bieżącego segmentu. Kiedy program asemblujący napotka dyrektywę ORG, obliczana jest wartość wyrażenie i zmieniana wartość licznika położenia dla bieżącego segmentu. Jeśli instrukcja ORG wystąpi w segmencie absolutnym, to do licznika położenia jest zapisywana wartość adresu absolutnego. Jeśli instrukcja ORG wystąpi w segmencie relokowalnym, to do licznika położenia zapisywana jest wartość określająca offset wyspecyfikowanego wyrażenia. Dyrektywa ORG zmienia licznik położenia, nie tworząc przy tym nowego segmentu. Użycie tej dyrektywy może powodować powstawanie dziur w segmencie. W segmencie absolutnym licznik położenia może nie odnosić się do wcześniejszego adresu będącego adresem bazowym segmentu. wyrażenie

Przykłady: ORG ORG ORG ORG

100H RESTART EXIT1 ($ + 16) AND 0FFF0H

7

USING Dyrektywa USING określa, który bank rejestrów ma być użyty dla kodowania rejestrów AR0 do AR7. Jej format jest określony jak poniżej: USING

wyrażenie

wyrażenie jest numerem banku rejestrów z zakresu 0 do 3. Dyrektywa USING nie generuje żadnego kodu zmieniającego bank rejestrów, dlatego należy się upewnić, że wybrano właściwy bank rejestrów. Do zmiany banku rejestrów można użyć poniższy przykład, w którym wybrano bank 2 rejestrów: PUSH PSW MOV PSW,#(2 SHL 3) ... ...

;zapamiętanie PSW/banku rejestrów ;wybór banku 2 rejestrów ;inne instrukcje

... ... POP PSW

;przywrócenie PSW/banku rejestrów

Bank rejestrów wybrany przez dyrektywę USING jest zaznaczany w pliku *.obj, a przestrzeń pamięci wymagana przez ten bank rejestrów jest rezerwowana przez linker. Wartości AR0 do AR7 są obliczane jako absolutne adresy rejestrów R0 do R7 w banku rejestrów określonym przez dyrektywę USING. Niektóre instrukcje jak PUSH i POP umożliwiają tylko użycie absolutnych adresów rejestrów. Domyślnie do symboli AR0 do AR7 przypisane są rejestry banku 0. USING 3 PUSH AR2

;odłóż na stos rejestr 2 z banku 3

USING 1 PUSH AR2

;odłóż na stos rejestr 2 z banku 1

UWAGA. Kiedy do zdefiniowania symboli dla ARn użyta jest dyrektywa EQU, to adres rejestru Rn jest obliczany w momencie definiowania symbolu, a nie w miejscu jego użycia. Kiedy dyrektywa USING zmienia później bank rejestrów, zdefiniowany symbol nie ma właściwego adresu rejestru ARn i generowany kod jest prawdopodobnie niepoprawny.

7.

Inne dyrektywy

NAME Dyrektywa NAME określa nazwę, która będzie użyta dla oznaczenia modułu obiektowego wygenerowanego na podstawie bieżącego programu. Nazwa pliku obiektowego nie jest nazwą modułu obiektowego. Nazwa modułu obiektowego jest wbudowana w plik obiektowy. Dyrektywa NAME ma następujący format: NAME

nazwa_modułu

jest nazwą, która będzie użyta do oznaczenia modułu obiektowego. Jej długość nie może przekroczyć 40 znaków. Przy określaniu nazwy modułu należy przestrzegać zasad określonych dla nazw symbolicznych. W danym pliku programu dyrektywa NAME może być użyta tylko jeden raz. Jeśli omawiana dyrektywa nie zostanie w ogóle użyta, to nazwą modułu obiektowego będzie nazwa pliku źródłowego bez rozszerzenia. nazwa_modułu

Przykład: NAME

MOJ_MODUL

8

END Dyrektywa END określa koniec modułu asemblerowego. Tekst, który występuje za dyrektywą END jest ignorowany przez program asemblujący. Dyrektywa END jest wymagana w każdym pliku asemblerowym. Przykład: END

8.

Symbole

Symbol jest nazwą definiowaną w celu reprezentacji wartości, bloku tekstu, adresu lub nazwy rejestru. Symbole mogą być również używane do reprezentowania stałych numerycznych i wyrażeń. Symbole mogą składać się z maksymalnie 31 znaków należących do poniższej listy:

A-Z, a-z, 0-9, _, ? Nazwa symbolu może rozpoczynać się od dowolnego z tych znaków, za wyjątkiem cyfr 0-9. Symbole mogą być definiowane w wielu różnych przypadkach. Można definiować symbol do reprezentacji wyrażeń: NUMER PRAWDA FALSZ

EQU SET SET

5 1 0

etykiet w programie ETYKIETA_1: DJNZ R0, ETYKIETA_1 lub odniesień do adresu zmiennej BUFOR_SZER DATA

99H

Symbole są używane w całym programie asemblerowym, gdyż są łatwiejsze do zrozumienia i zapamiętania, niż adres lub stała numeryczna.

9.

Etykiety

Etykieta definiuje „miejsce” (adres) w przestrzeni programu lub danych. Wszystkie zasady dotyczące tworzenia nazw symbolicznych mają zastosowanie przy tworzeniu etykiet. Podczas ich definiowania, etykieta musi być pierwszym polem tekstowym w linii. Może być ona poprzedzona znakami tabulacji i/lub spacji. Znak dwukropka (:) musi wystąpić bezpośrednio po nazwie symbolicznej etykiety, aby można było rozpoznać, że jest to etykieta. W linii może być zdefiniowana tylko jedna etykieta. Na przykład: ETYK_1: ETYK_2: LICZBY: KOPIUJ:

DS

2

DB 27, 33, ‘ZNAKI’, 0 MOV R6, #12H

;etykieta na siebie samą ;etykieta na stałe wartości ;etykieta na instrukcję w programie

W powyższym przykładzie, ETYK_1, ETYK_2, LICZBY i KOPIUJ są etykietami. Etykieta może odnosić się do kodu programu, przestrzeni zmiennych w wewnętrznej lub zewnętrznej pamięci danych lub stałej przechowywanej w pamięci programu. Przy definiowaniu etykiety automatycznie przypisywana jest jej bieżącą wartość licznika położenia w danym segmencie. Etykieta jest również używana w instrukcjach skoków, do wskazania miejsca (adresu) przeznaczenia. Instrukcja występująca za etykieta jest tą instrukcją, która będzie wykonywana po skoku pod adres programu wskazany etykietą. W programie można nie tylko wykonywać skoki pod określone etykiety, lecz także wywoływać podprogramy określone etykietą. W takim przypadku wykonywany jest kod znajdujący się za etykieta, aż do napotkania instrukcji asemblerowej RET.

9

10. Wyrażenia i operatory Operand (argument operacji) może być stałą numeryczną, symbolem, ciągiem znakowym lub wyrażeniem. Operatory są używane do łączenia i porównywania operandów wewnątrz programu asemblerowego. Operatory nie są instrukcjami języka asemblera, ani nie generują kodu asemblerowego. Reprezentują tylko operacje, które są szacowane w czasie asemblacji programu. Dlatego operatory mogą obejmować tylko obliczenia wartości, które są znane podczas asemblacji programu. Wyrażenie jest połączeniem liczb, ciągów znakowych, symboli i operatorów, które podlega zamianie na 16bitowaą wartość binarną. Wyrażenia są szacowane podczas asemblacji i dlatego mogą być używane do obliczania wartości, które w innym przypadku byłyby trudne do wyznaczenia wcześniej. 10.1

Liczby

Liczby mogą być określane jako wartości: szesnastkowe, dziesiętne, ósemkowe lub dwójkowe. Podstawa liczby jest określana przez ostatni znak w zapisie liczby. Liczba, która jest zapisana bez specyfikatora podstawy, jest interpretowana jako liczba dziesiętna. Poniższa tabela pokazuje specyfikatory podstawy liczb, przyrostki i przykłady. Podstawa Szesnastkowa Dziesiętna Ósemkowa Dwójkowa

Przyrostek H, h D, d O, o, Q, q B, b

Dopuszczalne znaki 0-9, A-F, a-f 0-9 0-7 0i1

Przykłady 1234H 0A0F0H 0F0H 1a24h 34fcH 123 23D 2092d 172q 34Q 345o 44O 1001011b 10011B

Pierwszym znakiem liczby musi być zawsze cyfra z zakresu 0 do 9. Dlatego liczby szesnastkowe, których zapis wartości zaczyna się od litery muszą być poprzedzone cyfrą 0. 10.2

Znaki

Program asemblujący dopuszcza użycie znaków ASCII w wyrażeniach do tworzenia wartości numerycznych. Wyrażenie takie może składać się maksymalnie z dwóch znaków objętych pojedynczym apostrofem (‘). Umieszczenie większej ilości znaków spowoduje wygenerowanie błędu podczas asemblacji. Poniżej przedstawiono kilka przykładów: ‘A’ ‘AB’ ‘a’ ‘ab’ ‘’ ‘abc’

jest przeliczane na wartość jest przeliczane na wartość jest przeliczane na wartość jest przeliczane na wartość ciąg pusty jest przeliczany generuje BŁĄD

0041H 4142H 0061H 6162H na wartość 0000H

Znaki można również używać w każdym miejscu programu, gdzie wymagane są dane bezpośrednie. LITERA_A

EQU

TEST:

MOV @R0,#’F’ SUBB A,#’0’

10.3

‘A’

Ciągi znaków

Ciągi znaków mogą być używane w połączeniu z dyrektywą DB do definiowania wiadomości używanych w programie. Taki ciąg musi być objęty pojedynczym apostrofem (‘). Na przykład: WIADOMOSC

DB

‘Wcisnij dowolny klawisz, aby kotynuowac.’

generuje szesnastkowe dane (57H, 63H, 69H, 73H, 6EH 69H 6AH, ..., 61H, 63H, 2EH) rozpoczynając od adresu oznaczonego etykietą WIADOMOSC. Ciągi i dane liczbowe mogą być łączone ze sobą w jednej linii. Na przykład: EOL_WIAD

DB

‘Koniec linii’, 00H

10

dodaje wartość 00H na koniec ciągu ‘Koniec linii’. Aby wstawić w definiowanym ciągu znakowym znak pojedynczego apostrofu, należy wyspecyfikować go dwukrotnie pod rząd. MSG

DB

‘ISN’’T A QUOTE REQUIRED HERE?’

11