MCS-51
Dyrektywy asemblerowe

Kontrolowanie adresów w segmentach

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

ORG

Implementacja: ASEM-51, Keil

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
  • 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.
Uwaga W większości przypadków asemblery są programami wieloprzebiegowymi. W pierwszym przebiegu zbierane są informacje o symbolach oraz określany jest rozmiar każdego z rozkazów. W drugim przebiegu obliczane są wartości ewentualnych odniesień w tył. Z tego powodu wyrażenia używane w dyrektywie ORG nie mogą zawierać odniesień w przód.

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, dlatego użwanie tej dyrektywy może powodować powstawanie dziur w danym segmencie. W segmencie absolutnym licznik położenia może nie odnosić się do wcześniejszego adresu będącego adresem bazowym segmentu.

W poniższym przykładzie dyrektywy ORG użyto do umieszczenia pod odpowiednim adresem skoku do podprogramu obsługi przerwania od licznika T0.

CSEG AT 2000h
     SJMP POCZ
ORG 200Bh
     SJMP LICZNIK_T0
     ...
     ...

Cały program w powyższym przykładzie zaczyna się od adresu 2000h. Obsługa większej ilości przerwań i ewentualna konieczność zmiany adresu początkowego (np. gdy rezygnujemy z uruchamiania stworzonego programu pod kontrolą programu monitora), pociągałaby za sobą konieczność przeliczenie adresów użytych we wszystkich dyrektywach ORG. Dlatego w takim przypadku lepszym rozwiązaniem jest zdefiniowanie symbolu za pomocą dyrektywy EQU (patrz punkt dotyczący definiowania symboli), który będzie niejako ekwiwalentem adresu początkowego, od którego rozpoczyna się tworzony program. W dyrektywach ORG pojawią się wtedy, zamiast stałych wartości liczbowych, wyrażenia, które zostaną przeliczone na odpowiednią wartość adresu w momencie asemblacji programu. Program napisany w ten sposób wymaga w takim wypadku zmiany adresu bazowego tylko w jednym miejscu.

BASE_ADDRSS EQU 2000h

CSEG AT BASE_ADDRESS
     SJMP POCZ
ORG BASE_ADDRESS + 0Bh
     SJMP LICZNIK_T0
     ...
     ...

USING

Implementacja: ASEM-51, Keil

Dyrektywa USING określa, który bank rejestrów ma być użyty przy określeniu wartości symboli specjalnych AR0 do AR7. Wartości tych symboli są obliczane jako absolutne adresy rejestrów R0 do R7 w banku o numerze określonym właśnie przez omawianą dyrektywę. Jej format jest następujący:

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 zawsze należy się upewnić, że wybrano właściwy bank rejestrów. Jeśli konieczna jest zmiana aktywnego banku rejestrów, to można ją przeprowadzić w sposób pokazany poniżej.

1 PUSH PSW                ;zapamiętanie PSW (banku rejestrów)
2 MOV PSW,#(2 SHL 3)	;wybór 2. banku rejestrów
3 ...
4 ...
5                        ;inne instrukcje
6 ...
7 ...
8 POP PSW                 ;przywrócenie PSW (banku rejestrów)

W powyższym przykładzie w instrukcji 2 jako aktywny wybrano drugi bank rejestrów. Jednocześnie wcześniej (linia 1) odłożono na stos bieżącą zawartość rejestru PSW. Pozwala to na późniejsze odtworzenie jego zawartości (linia 8). Przedstawiony ciąg instrukcji może być zastosowany w np. podprogramach obsługi przerwań, gdzie zamiast odłożenia na stos wszystkich rejestrów danego banku dokonuje się zmiany numeru banku aktywnego.

W asemblerze firmy Keil, 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