Assembly 寻址模式和MOV指令 - Assembly汇编
大多数汇编语言指令的要求,要被处理的操作数。提供一个操作数地址要被处理的数据被存储的位置。某些指令不需要操作数,而其他一些指令可能需要一个,两个或三个操作数。
当一个指令需要两个操作数,第一个操作数是一般的目的,其中包含在一个寄存器或内存位置和第二个操作数源数据。源码包含要传送的数据(立即寻址)或(寄存器或存储器)中的数据的地址。一般来说,操作后的源数据将保持不变。
解决的三种基本模式是:
寄存器寻址
立即寻址
存储器寻址
寄存器寻址
在这种寻址方式中,寄存器包含操作数。根据不同的指令,寄存器可能是第一个操作数,第二个操作数或两者兼而有之。
例如,
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