Montage - Adressierungsmodi
Die meisten Assembler-Anweisungen erfordern die Verarbeitung von Operanden. Eine Operandenadresse gibt den Ort an, an dem die zu verarbeitenden Daten gespeichert werden. Einige Anweisungen erfordern keinen Operanden, während andere Anweisungen einen, zwei oder drei Operanden erfordern können.
Wenn ein Befehl zwei Operanden erfordert, ist der erste Operand im Allgemeinen das Ziel, das Daten in einem Register oder Speicherplatz enthält, und der zweite Operand ist die Quelle. Die Quelle enthält entweder die zu liefernden Daten (sofortige Adressierung) oder die Adresse (im Register oder Speicher) der Daten. Im Allgemeinen bleiben die Quelldaten nach der Operation unverändert.
Die drei grundlegenden Adressierungsmodi sind:
- Adressierung registrieren
- Sofortige Adressierung
- Speicheradressierung
Adressierung registrieren
In diesem Adressierungsmodus enthält ein Register den Operanden. Abhängig von der Anweisung kann das Register der erste Operand, der zweite Operand oder beides sein.
Zum Beispiel,
MOV DX, TAX_RATE ; Register in first operand
MOV COUNT, CX ; Register in second operand
MOV EAX, EBX ; Both the operands are in registers
Da die Verarbeitung von Daten zwischen Registern keinen Speicher umfasst, bietet sie die schnellste Verarbeitung von Daten.
Sofortige Adressierung
Ein unmittelbarer Operand hat einen konstanten Wert oder einen Ausdruck. Wenn ein Befehl mit zwei Operanden eine sofortige Adressierung verwendet, kann der erste Operand ein Register oder ein Speicherort sein, und der zweite Operand ist eine unmittelbare Konstante. Der erste Operand definiert die Länge der Daten.
Zum Beispiel,
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
Direkte Speicheradressierung
Wenn Operanden im Speicheradressierungsmodus angegeben werden, ist ein direkter Zugriff auf den Hauptspeicher, normalerweise auf das Datensegment, erforderlich. Diese Art der Adressierung führt zu einer langsameren Verarbeitung von Daten. Um den genauen Speicherort der Daten im Speicher zu ermitteln, benötigen wir die Segmentstartadresse, die normalerweise im DS-Register enthalten ist, und einen Versatzwert. Dieser Offsetwert wird auch genannteffective address.
Im direkten Adressierungsmodus wird der Versatzwert direkt als Teil des Befehls angegeben, der normalerweise durch den Variablennamen angegeben wird. Der Assembler berechnet den Versatzwert und verwaltet eine Symboltabelle, in der die Versatzwerte aller im Programm verwendeten Variablen gespeichert sind.
Bei der direkten Speicheradressierung bezieht sich einer der Operanden auf einen Speicherort und der andere Operand auf ein Register.
Zum Beispiel,
ADD BYTE_VALUE, DL ; Adds the register in the memory location
MOV BX, WORD_VALUE ; Operand from the memory is added to register
Direct-Offset-Adressierung
Dieser Adressierungsmodus verwendet die arithmetischen Operatoren, um eine Adresse zu ändern. Schauen Sie sich beispielsweise die folgenden Definitionen an, die Datentabellen definieren:
BYTE_TABLE DB 14, 15, 22, 45 ; Tables of bytes
WORD_TABLE DW 134, 345, 564, 123 ; Tables of words
Die folgenden Operationen greifen auf Daten aus den Tabellen im Speicher in Register zu -
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
Indirekte Speicheradressierung
Dieser Adressierungsmodus nutzt die Fähigkeit des Computers zur Segmentierung: Versatzadressierung . Im Allgemeinen werden zu diesem Zweck die Basisregister EBX, EBP (oder BX, BP) und die Indexregister (DI, SI) verwendet, die in eckigen Klammern für Speicherreferenzen codiert sind.
Die indirekte Adressierung wird im Allgemeinen für Variablen verwendet, die mehrere Elemente wie Arrays enthalten. Die Startadresse des Arrays wird beispielsweise im EBX-Register gespeichert.
Das folgende Codeausschnitt zeigt, wie auf verschiedene Elemente der Variablen zugegriffen wird.
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
Die MOV-Anweisung
Wir haben bereits den MOV-Befehl verwendet, der zum Verschieben von Daten von einem Speicherplatz in einen anderen verwendet wird. Der MOV-Befehl benötigt zwei Operanden.
Syntax
Die Syntax des MOV-Befehls lautet -
MOV destination, source
Der MOV-Befehl kann eine der folgenden fünf Formen haben:
MOV register, register
MOV register, immediate
MOV memory, immediate
MOV register, memory
MOV memory, register
Bitte beachten Sie, dass -
- Beide Operanden im MOV-Betrieb sollten gleich groß sein
- Der Wert des Quelloperanden bleibt unverändert
Der MOV-Befehl verursacht manchmal Mehrdeutigkeiten. Schauen Sie sich zum Beispiel die Aussagen an -
MOV EBX, [MY_TABLE] ; Effective Address of MY_TABLE in EBX
MOV [EBX], 110 ; MY_TABLE[0] = 110
Es ist nicht klar, ob Sie ein Byte-Äquivalent oder ein Wort-Äquivalent der Zahl 110 verschieben möchten. In solchen Fällen ist es ratsam, a zu verwenden type specifier.
Die folgende Tabelle zeigt einige der gängigen Typspezifizierer -
Typspezifizierer | Bytes adressiert |
---|---|
BYTE | 1 |
WORT | 2 |
DWORD | 4 |
QWORT | 8 |
TBYTE | 10 |
Beispiel
Das folgende Programm veranschaulicht einige der oben diskutierten Konzepte. Es speichert einen Namen 'Zara Ali' im Datenbereich des Speichers, ändert dann programmgesteuert seinen Wert in einen anderen Namen 'Nuha Ali' und zeigt beide Namen an.
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 '
Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:
Zara Ali Nuha Ali