彙編 -定址模式



大多數組合語言指令都需要處理運算元。運算元地址提供了儲存要處理資料的的位置。一些指令不需要運算元,而另一些指令可能需要一個、兩個或三個運算元。

當指令需要兩個運算元時,第一個運算元通常是目標運算元,它包含暫存器或記憶體位置中的資料,第二個運算元是源運算元。源運算元包含要傳遞的資料(立即定址)或資料的地址(在暫存器或記憶體中)。通常,操作後源資料保持不變。

三種基本的定址模式是 -

  • 暫存器定址
  • 立即定址
  • 記憶體定址

暫存器定址

在這種定址模式下,暫存器包含運算元。根據指令的不同,暫存器可以是第一個運算元、第二個運算元或兩者。

例如,

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
廣告