Zespół - tryby adresowania
Większość instrukcji języka asemblerowego wymaga przetwarzania argumentów. Adres argumentu określa lokalizację, w której przechowywane są dane do przetworzenia. Niektóre instrukcje nie wymagają operandu, podczas gdy inne instrukcje mogą wymagać jednego, dwóch lub trzech operandów.
Gdy instrukcja wymaga dwóch operandów, pierwszy argument jest zwykle miejscem docelowym, który zawiera dane w rejestrze lub komórce pamięci, a drugi argument jest źródłem. Źródło zawiera dane do dostarczenia (adresowanie bezpośrednie) lub adres (w rejestrze lub pamięci) danych. Generalnie dane źródłowe pozostają niezmienione po operacji.
Trzy podstawowe tryby adresowania to -
- Zarejestruj adresowanie
- Natychmiastowe adresowanie
- Adresowanie pamięci
Zarejestruj adresowanie
W tym trybie adresowania rejestr zawiera operand. W zależności od instrukcji rejestr może być pierwszym operandem, drugim operandem lub obydwoma.
Na przykład,
MOV DX, TAX_RATE ; Register in first operand
MOV COUNT, CX ; Register in second operand
MOV EAX, EBX ; Both the operands are in registers
Ponieważ przetwarzanie danych między rejestrami nie obejmuje pamięci, zapewnia najszybsze przetwarzanie danych.
Natychmiastowe adresowanie
Bezpośredni operand ma stałą wartość lub wyrażenie. Gdy instrukcja z dwoma argumentami używa adresowania bezpośredniego, pierwszy argument może być rejestrem lub lokalizacją pamięci, a drugi argument jest natychmiastową stałą. Pierwszy operand określa długość danych.
Na przykład,
BYTE_VALUE DB 150 ; A byte value is defined
WORD_VALUE DW 300 ; A word value is defined
ADD BYTE_VALUE, 65 ; An immediate operand 65 is added
MOV AX, 45H ; Immediate constant 45H is transferred to AX
Bezpośrednie adresowanie pamięci
Gdy operandy są określone w trybie adresowania pamięci, wymagany jest bezpośredni dostęp do pamięci głównej, zwykle do segmentu danych. Ten sposób adresowania skutkuje wolniejszym przetwarzaniem danych. Aby zlokalizować dokładną lokalizację danych w pamięci, potrzebujemy adresu początkowego segmentu, który zwykle znajduje się w rejestrze DS i wartości przesunięcia. Ta wartość przesunięcia jest również nazywanaeffective address.
W trybie adresowania bezpośredniego wartość offsetu jest określana bezpośrednio jako część instrukcji, zwykle wskazywana przez nazwę zmiennej. Asembler oblicza wartość przesunięcia i utrzymuje tabelę symboli, w której przechowywane są wartości przesunięć wszystkich zmiennych używanych w programie.
W bezpośrednim adresowaniu pamięci jeden z argumentów odnosi się do miejsca w pamięci, a drugi do rejestru.
Na przykład,
ADD BYTE_VALUE, DL ; Adds the register in the memory location
MOV BX, WORD_VALUE ; Operand from the memory is added to register
Adresowanie z bezpośrednim przesunięciem
Ten tryb adresowania wykorzystuje operatory arytmetyczne do modyfikacji adresu. Na przykład spójrz na następujące definicje, które definiują tabele danych -
BYTE_TABLE DB 14, 15, 22, 45 ; Tables of bytes
WORD_TABLE DW 134, 345, 564, 123 ; Tables of words
Następujące operacje uzyskują dostęp do danych z tablic w pamięci do rejestrów -
MOV CL, BYTE_TABLE[2] ; Gets the 3rd element of the BYTE_TABLE
MOV CL, BYTE_TABLE + 2 ; Gets the 3rd element of the BYTE_TABLE
MOV CX, WORD_TABLE[3] ; Gets the 4th element of the WORD_TABLE
MOV CX, WORD_TABLE + 3 ; Gets the 4th element of the WORD_TABLE
Pośrednie adresowanie pamięci
Ten tryb adresowania wykorzystuje zdolność komputera do adresowania Segment: Offset . Generalnie do tego celu wykorzystywane są rejestry bazowe EBX, EBP (lub BX, BP) i rejestry indeksowe (DI, SI), zakodowane w nawiasach kwadratowych jako odniesienia do pamięci.
Adresowanie pośrednie jest zwykle używane w przypadku zmiennych zawierających kilka elementów, takich jak tablice. Początkowy adres tablicy jest przechowywany, powiedzmy, w rejestrze EBX.
Poniższy fragment kodu pokazuje, jak uzyskać dostęp do różnych elementów zmiennej.
MY_TABLE TIMES 10 DW 0 ; Allocates 10 words (2 bytes) each initialized to 0
MOV EBX, [MY_TABLE] ; Effective Address of MY_TABLE in EBX
MOV [EBX], 110 ; MY_TABLE[0] = 110
ADD EBX, 2 ; EBX = EBX +2
MOV [EBX], 123 ; MY_TABLE[1] = 123
Instrukcja MOV
Skorzystaliśmy już z instrukcji MOV, która służy do przenoszenia danych z jednej przestrzeni pamięci do drugiej. Instrukcja MOV przyjmuje dwa operandy.
Składnia
Składnia instrukcji MOV to -
MOV destination, source
Instrukcja MOV może mieć jedną z następujących pięciu form -
MOV register, register
MOV register, immediate
MOV memory, immediate
MOV register, memory
MOV memory, register
Należy pamiętać, że -
- Oba operandy w operacji MOV powinny mieć ten sam rozmiar
- Wartość argumentu źródłowego pozostaje niezmieniona
Instrukcja MOV czasami powoduje niejednoznaczność. Na przykład spójrz na stwierdzenia -
MOV EBX, [MY_TABLE] ; Effective Address of MY_TABLE in EBX
MOV [EBX], 110 ; MY_TABLE[0] = 110
Nie jest jasne, czy chcesz przesunąć równoważnik bajtowy, czy odpowiednik słowa liczby 110. W takich przypadkach rozsądnie jest użyć znaku type specifier.
W poniższej tabeli przedstawiono niektóre typowe specyfikatory typu -
Specyfikator typu | Adresowane bajty |
---|---|
BAJT | 1 |
SŁOWO | 2 |
DWORD | 4 |
QWORD | 8 |
TBYTE | 10 |
Przykład
Poniższy program ilustruje niektóre z omówionych powyżej koncepcji. Przechowuje nazwę „Zara Ali” w sekcji danych pamięci, a następnie programowo zmienia jej wartość na inną nazwę „Nuha Ali” i wyświetla obie nazwy.
section .text
global _start ;must be declared for linker (ld)
_start: ;tell linker entry point
;writing the name 'Zara Ali'
mov edx,9 ;message length
mov ecx, name ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov [name], dword 'Nuha' ; Changed the name to Nuha Ali
;writing the name 'Nuha Ali'
mov edx,8 ;message length
mov ecx,name ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
name db 'Zara Ali '
Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -
Zara Ali Nuha Ali