
彙編 -定址模式
大多數組合語言指令都需要處理運算元。運算元地址提供了儲存要處理資料的的位置。一些指令不需要運算元,而另一些指令可能需要一個、兩個或三個運算元。
當指令需要兩個運算元時,第一個運算元通常是目標運算元,它包含暫存器或記憶體位置中的資料,第二個運算元是源運算元。源運算元包含要傳遞的資料(立即定址)或資料的地址(在暫存器或記憶體中)。通常,操作後源資料保持不變。
三種基本的定址模式是 -
- 暫存器定址
- 立即定址
- 記憶體定址
暫存器定址
在這種定址模式下,暫存器包含運算元。根據指令的不同,暫存器可以是第一個運算元、第二個運算元或兩者。
例如,
MOV DX, TAX_RATE ; Register in first operand MOV COUNT, CX ; Register in second operand MOV EAX, EBX ; Both the operands are in registers
由於暫存器之間的資料處理不涉及記憶體,因此它提供了最快的資料處理速度。
立即定址
立即運算元具有常數值或表示式。當具有兩個運算元的指令使用立即定址時,第一個運算元可以是暫存器或記憶體位置,第二個運算元是立即常數。第一個運算元定義資料的長度。
例如,
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
直接記憶體定址
當運算元在記憶體定址模式中指定時,需要直接訪問主記憶體,通常是資料段。這種定址方式導致資料處理速度較慢。為了找到記憶體中資料的精確位置,我們需要段起始地址(通常在 DS 暫存器中找到)和偏移量值。此偏移量值也稱為有效地址。
在直接定址模式下,偏移量值直接作為指令的一部分指定,通常由變數名指示。彙編器計算偏移量值並維護一個符號表,該符號表儲存程式中使用的所有變數的偏移量值。
在直接記憶體定址中,一個運算元引用記憶體位置,另一個運算元引用暫存器。
例如,
ADD BYTE_VALUE, DL ; Adds the register in the memory location MOV BX, WORD_VALUE ; Operand from the memory is added to register
直接偏移定址
此定址模式使用算術運算子修改地址。例如,檢視以下定義,這些定義定義了資料表 -
BYTE_TABLE DB 14, 15, 22, 45 ; Tables of bytes WORD_TABLE DW 134, 345, 564, 123 ; Tables of words
以下操作將記憶體中的表中的資料訪問到暫存器中 -
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
間接記憶體定址
此定址模式利用計算機的段:偏移定址能力。通常,基址暫存器 EBX、EBP(或 BX、BP)和索引暫存器(DI、SI)在記憶體引用中用方括號編碼,用於此目的。
間接定址通常用於包含多個元素的變數,例如陣列。陣列的起始地址儲存在例如 EBX 暫存器中。
以下程式碼片段顯示瞭如何訪問變數的不同元素。
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
MOV 指令
我們已經使用了 MOV 指令,該指令用於將資料從一個儲存空間移動到另一個儲存空間。MOV 指令採用兩個運算元。
語法
MOV 指令的語法為 -
MOV destination, source
MOV 指令可以具有以下五種形式之一 -
MOV register, register MOV register, immediate MOV memory, immediate MOV register, memory MOV memory, register
請注意 -
- MOV 操作中的兩個運算元應具有相同的大小
- 源運算元的值保持不變
MOV 指令有時會導致歧義。例如,檢視以下語句 -
MOV EBX, [MY_TABLE] ; Effective Address of MY_TABLE in EBX MOV [EBX], 110 ; MY_TABLE[0] = 110
不清楚您是想移動位元組等效值還是數字 110 的字等效值。在這種情況下,最好使用型別說明符。
下表顯示了一些常見的型別說明符 -
型別說明符 | 定址位元組數 |
---|---|
BYTE | 1 |
WORD | 2 |
DWORD | 4 |
QWORD | 8 |
TBYTE | 10 |
示例
以下程式說明了上面討論的一些概念。它將名稱“Zara Ali”儲存在記憶體的資料段中,然後以程式設計方式將其值更改為另一個名稱“Nuha Ali”,並顯示這兩個名稱。
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 '
編譯並執行上述程式碼後,會產生以下結果 -
Zara Ali Nuha Ali