Maciej Kostyra |
18-12-2000 |
Grupa III |
|
Temat:
|
Assembler |
Wyrażenia - CD
TYPE
Uznanie napisu TYPE exp, w którym exp jest dowolnym wyrażeniem, za nazwę stałej określającej typ tego wyrażenia zgodnie z następującym zestawieniem:
TYP WARTOŚĆ STAŁEJ
BYTE 1
WORD 2
DWORD 4
FWORD 6
QWORD 8
TBYTE 10
NEAR 0ffffh
FAR 0fffeh
Przykład:
W zasięgu deklaracji:
Fix DW ?
wyrażenie: Type Fix reprezentuje daną o wartości 2.
*
Uznanie, że wyrażenie expL*expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje ich iloczyn.
Przykład:
W zasięgu deklaracji
Fix DW 3 dup(?),0
wyrażenie: Type Fix*length Fix reprezentuje daną o wartości 6
/
Uznanie, że wyrażenie expL/expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje ich iloraz.
Przykład:
W zasięgu deklaracji:
Fix DQ 1,2,3
Wyrażenie size Fix/2 ma wartość 4
MOD
Uznanie, że wyrażenie expL MOD expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje resztę z dzielenia expL przez expR.
Przykład:
Napis: 12 MOD 5
Reprezentuje daną o wartości 2
SHL
Uznanie, że wyrażenie expL SHL expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje daną o reprezentacji dwójkowej powstałą z przesunięcia reprezentacji dwójkowej expL o expR pozycji w lewo.
Przykład:
Napis: 13 SHL 2
reprezentuje daną o wartości 52
SHR
Uznanie, że wyrażenie expL SHR expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje daną o reprezentacji dwójkowej powstałą z przesunięcia reprezentacji dwójkowej expL o expR pozycji w prawo.
Przykład:
Napis: 13 SHR 2 reprezentuje daną o wartości 3
+
Uznanie, że wyrażenie expL + expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje ich sumę.
Przykład:
Napis: 13 + 2 reprezentuje daną o wartości 15
-
Uznanie, że wyrażenie expL - expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje różnicę expL i expR.
Przykład:
Napis: 13 - 2 reprezentuje daną o wartości 11
EQ
Uznanie, że wyrażenie expL EQ expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje daną o wartości -1, jeśli expL jest równe expR, albo daną o wartości 0 w przeciwnym razie.
Przykład:
Napis: 12 EQ 2+10
reprezentuje daną o wartości -1
GE
Uznanie, że wyrażenie expL GE expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje daną o wartości -1, jeśli expL jest większe lub równe expR, albo daną o wartości 0 w przeciwnym razie.
Przykład:
Napis: 12 GE 2+10 reprezentuje daną o wartości -1
GT
Uznanie, że wyrażenie expL GT expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje daną o wartości -1, jeśli expL jest większe niż expR, albo daną o wartości 0 w przeciwnym razie.
Przykład:
Napis: 12 GT 12 reprezentuje daną o wartości 0
LE
Uznanie, że wyrażenie expL LE expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje daną o wartości -1, jeśli expL jest mniejsze lub równe expR, albo daną o wartości 0 w przeciwnym razie.
Przykład:
Napis: 6 LE 5 reprezentuje daną o wartości 0
LT
Uznanie, że wyrażenie expL LT expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje daną o wartości -1, jeśli expL jest mniejsze niż expR, albo daną o wartości 0 w przeciwnym razie.
Przykład:
Napis: 2 LT -1 reprezentuje daną o wartości 0
NE
Uznanie, że wyrażenie expL NE expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje daną o wartości -1, jeśli expL nie jest równe expR, albo daną o wartości 0 w przeciwnym razie.
Przykład:
Napis: 12 NE 2 reprezentuje daną o wartości -1
NOT
Uznanie, że wyrażenie NOT exp, w którym exp jest wyrażeniem stałym, reprezentuje daną powstałą z danej reprezentowanej przez exp przez zanegowanie wszystkich bitów jej reprezentacji dwójkowej.
Przykład:
Napis: NOT -6 reprezentuje daną o wartości 5
AND
Uznanie, że wyrażenie expL AND expR, w którym expL i expR są wyrażeniami stałymi, reprezentuje daną powstałą z danych reprezentowanych przez expL i expR przez równoległe wyznaczenie iloczynu logicznego na wszystkich odpowiadających sobie bitach ich reprezentacji dwójkowych.
SHORT
Uznanie, że wyrażenie SHORT exp, w którym exp jest wyrażeniem stałym, reprezentuje przemieszczenie różniące się od bieżącego przemieszczenia we właśnie kompilowanym segmencie o nie więcej niż 127 i nie mniej niż -128.
Przykład:
Napis: jmp short Lab jest rozkazem skoku krótkiego
UWAGA. Wyrażenia takie, jak np.:
OFFSET FIX
i
SEG FIX
w których FIX jest etykietą zmiennej, są istotnie wyrażeniami stałymi. Wartość pierwszego z nich (określająca przemieszczenie w segmencie przykładowej zmiennej FIX) jest bowiem znana już na etapie kompilowania programu, a wartość drugiego (określająca numer segmentu, w którym znajduje się rozpatrywana zmienna) jest znana w momencie ładowania programu.
Przykłady. Wyrażenia:
(After - Before) / 2
WORD ptr FIX+1
FIX EQ RES
2+-3
Deklarowanie nazw stałych.
Do deklarowania nazw stałych służą dyrektywy EQU i = (równa się). Za pomocą dyrektywy EQU można deklarować nazwy znaków, nazwy literałów znakowych, nazwy liczb oraz etykiety, a za pomocą dyrektywy = (równa się) można zadeklarować jedynie nazwy liczb.
W ogólnym przypadku dyrektywa EQU ma postać:
name EQU exp
a dyrektywa = (równa się) ma postać:
name = exp
przy czym name jest deklarowaną nazwą stałej, a exp jest wyrażeniem stałym. Zabranie się aby identyfikator stanowiący nazwę stałej zadeklarowanej za pomocą dyrektywy EQU był deklarowany ponownie. Ograniczenie to nie dotyczy nazwy stałej zadeklarowanej za pomocą dyrektywy = (równa się).
Przykłady. Deklarowanie stałych:
W zasięgu deklaracji:
Fix DW B
Lab: mov ax,2
są poprawne m.in. następujące deklaracje stałych:
Count = 0
Higher EQU offset FIX+1
Greet EQU `Hello'
Lower EQU Higher-1
Count=Count+1
Next EQU Lab+2
Predefiniowany symbol $
Predefiniowany symbol $ (dolar) należy do tej samej kategorii co omówione uprzednio symbole @Data, @FarData itp. Symbol ten jest nazwą stałej o wartości równej aktualnemu przemieszczeniu we właśnie kompilowanym segmencie.
Przykłady. Użycie symbolu $:
Greet DB `Hello world'
span EQU $-Greet ;span=11
Adresowanie zmiennych
W dotychczasowych przykładach posługiwano się bardzo prostymi adresami danych i rozkazów. W ogólnym przypadku adres danej może być przedstawiany za pomocą wyrażenia postaci.
baza + indeks + przemieszczenie
w której baza i indeks są odpowiednio nazwami rejestru bazowego (BX, BP) i indeksowego (SI, DI), a przemieszczenie jest dowolnym wyrażeniem stałym.
Przykład. Adresowanie zmiennej:
Jeśli przyjąć, że w zasięgu dyrektywy uproszczonej .DATA znajduje się deklaracja:
Greet DB `Hello'
oraz, że w rejestrze DS znajduje się numer segmentu @Data umieszczony tam na przykład za pomocą pary rozkazów:
mov ax,@Data
mov ds,ax
to wykonanie każdej z następujących sekwencji rozkazów powoduje załadowanie do rejestru AL takiej samej danej:
mov al,'0' mov di,1
mov bx,1
mov al,[GREET + 4] mov al,[bx+GREET+di+2]
mov si,(offset GREET)+4 mov bp,1
mov al,[SI] mov di,offset GREET+2
mov al,[ds:bp+di+1]
mov bx,offset GREET
mov bx,4
mov al,[SI+BX]
Adres zmiennej powinien być ..... aby występowała zgodność typu zmiennej i użytego rozkazu. W szczególności oznacza to, że do zmiennej 8-bitowej można odwołać się tylko za pomocą rozkazu ładowania danych 8-bitowych, a odesłanie danej z pamięci na stos procesora może dotyczyć jedynie danej przypisanej zmiennej 16-bitowej. Wymaga się ponadto, aby na podstawie analizy zapisu rozkazu można było wywnioskować rozmiar danych, których dotyczy ten rozkaz
Przykłady. Konwersja typu wyrażenia:
Jeśli w zasięgu dyrektywy: Fix DW 13 znajduje się rozkaz pobrania danej 8-bitowej: mov al,[FIX]
to jest on użyty niepoprawnie, ponieważ Fix reprezentuje daną 16-bitową. Błąd ten można usunąć, zastępując rozpatrywny rozkaz rozkazem:
mov al,[byte ptr Fix]
rozkaz o postaci: inc [bx] jest niepoprawny, ponieważ na podstawie jego analizy nie można wywnioskować czy dotyczy zmiennej 8-bitowej, czy 16-bitowej. W pierwszym wypadku należy go przedstawić w postaci:
inc [byte ptr bx]
a w drugim postaci:
inc [word ptr BX]
przyjmuje się, że rozkaz postaci: mov ax,[b] jest poprawny, ponieważ na podstawie jego analizy można wywnioskować rozmiar danej, której dotyczy (16 bitów).
rozkaz postaci: push Fix w którym Fix jest nazwą zmiennej typu BYTE, jest niepoprawny ponieważ na stosie mogą być umieszczane tylko słowa. Błąd ten można usunąć zastępując rozpatrywany rozkaz rozkazem:
push word ptr Fix
Adresowanie rozkazów.
Adresowanie rozkazów pozostaje w związku z wykonaniem skoków i wywołaniem procedur. Jeśli w rozkazie skoku występuje słowo kluczowe SHORT, to skok jest krótki, a jeśli występuje słowo kluczowe NEAR, to skok jest bliski.
Wykonanie obu rodzajów skoku powoduje jedynie zmianę zawartości rejestru IP i nie narusza rejestru CS (rozkazy krótkie zajmują mniej miejsca niż bliskie, ale umożliwiają wykonanie skoku na odległość nie więcej niż 128 bajtów od miejsca wystąpienia rozkazu).
Jeśli w rozkazie występuje słowo kluczowe FAR to skok jest daleki. Jego wykonanie powoduje załadowanie zarówno rejestru CS, jak i IP.
Podczas kompilowania rozkazów skoku które nie zawierają wymienionych słów kluczowych domyślnie przyjmuje się słowo kluczowe NEAR, chyba że skok odbywa się do znanej już etykiety, która ma atrybut FAR. W takim przypadku skok uznaje się za daleki.
UWAGA. Należy unikać bliskich i krótkich rozkazów skoków międzysystemowych ponieważ ich użycie nie ma w większości przypadków sensu.
Assume CS:Code
Code1 Segment
Start:
jmp short Lab1
Lab3:
jmp Lab4 ;jmp short Lab4 i nop
Lab6 LABEL FAR
Jmp near ptr Lab7 ;wymagane near ptr
Lab8 LABEL FAR
mov ax,4c00h
int 21h
Lab7 LABEL FAR
jmp short Lab8 ;bez short byłoby far ptr
Lab1:
jmp FAR ptr Lab2
Lab4:
jmp far ptr Lab5
Code1 ENDS
ASSUME CS:Code2
Code2 Segment
Lab2:
jmp far ptr Lab3
Lab5 LABEL FAR
jmp Lab6 ;jmp far ptr Lab6
Code2 ENDS
Stack_ Segment Stack
DB 100h dup(?)
Stack_ ENDS
END START