将数据从一个变量复制到另一个变量

ari*_*ess 3 x86 assembly nasm

这是我编写的代码的一部分:

section .data
name db 'slm dada',0xa
lenname equ $-name
nane db 'bye '

section .text
global _start
_start:
mov edx, lenname
mov ecx, name
mov ebx, 1
mov eax, 4
int 80h

mov eax, [nane]           <- My questions are about
mov [name], dword eax     <- these 2 lines

mov edx, lenname
mov ecx, name
mov ebx, 1
mov eax, 4
int 80h

mov eax, 1
int 0x80
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

  1. 有没有办法不使用EAX寄存器将nane变量的值移动到name变量?

  2. 为什么我们需要使用类型修饰符?

Cod*_*ray 7

  1. 不,只使用一条指令就无法做到这一点.也就是说,你做不到:

    mov  [name], [nane]     ; invalid code!
    
    Run Code Online (Sandbox Code Playgroud)

    因为没有编码MOV带有两个内存操作数的指令:

    mov  mem, meg           ; non-existent instruction!
    
    Run Code Online (Sandbox Code Playgroud)

    唯一可用的形式MOV是:

    mov  reg, imm           ; place immediate/constant in register
    mov  mem, imm           ; store immediate/constant in memory
    mov  reg, reg           ; copy one register to another
    mov  reg, mem           ; load value from memory into register
    mov  mem, reg           ; store value from register into memory
    
    Run Code Online (Sandbox Code Playgroud)

    这就是你必须使用临时寄存器的原因.

    这里实际使用单一instruction-内存从一个位置移动到另一个数据的方式MOVS.这使用隐式操作数,但需要一些额外的设置才能正常工作,除了它本身就是一个慢速指令(用微码实现),因此使用MOV临时寄存器几乎总是一个更好的主意.

  2. 那里应该要求类型修饰符.事实上,NASM并不需要它.它组装此代码时没有错误:

    mov  eax, [nane]
    mov  [name], eax
    
    Run Code Online (Sandbox Code Playgroud)

    需要注意的是,如果你要包括类型修饰符(和你总是可以,只是要明确的),那么它不应该被放置在你原本它.汇编程序已经知道EAX寄存器是DWORD-sized.正确(显式)形式将是:

    mov  eax, dword [nane]
    mov  dword [name], eax
    
    Run Code Online (Sandbox Code Playgroud)

    但是,正如我所说,这实际上并不是必要的.汇编器可以告诉它是DWORD在地址处存储一个大小的值,name因为源操作数(EAX)本身是DWORD大小的.

    另见这个答案:我什么时候应该在x86中使用size指令?