Assembly 定址模式和MOV指令


大多數組合語言指令的要求,要被處理的運算元。提供一個運算元地址要被處理的資料被儲存的位置。某些指令不需要??運算元,而其他一些指令可能需要一個,兩個或三個運算元。

當一個指令需要兩個運算元,第一個運算元是一般的目的,其中包含在一個暫存器或記憶體位置和第二個運算元源資料。原始碼包含要傳送的資料(立即定址)或(暫存器或儲存器)中的資料的地址。一般來說,操作後的源資料將保持不變。

解決的三種基本模式是:

  • 暫存器定址

  • 立即定址

  • 儲存器定址

暫存器定址

在這種定址方式中,暫存器包含運算元。根據不同的指令,暫存器可能是第一個運算元,第二個運算元或兩者兼而有之。

例如,

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。在這種情況下,比較好的做法是使用型別說明符。

下表列出了一些常見的型別說明符:

Type Specifier Bytes addressed
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 yiibai
	
;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