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