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

时间:2017-06-22 08:46:26

标签: assembly x86 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

我有两个问题:

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

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

1 个答案:

答案 0 :(得分:7)

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

    mov  [name], [nane]     ; invalid code!
    

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

    mov  mem, meg           ; non-existent instruction!
    

    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
    

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

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

  2. 类型修饰符应该。事实上,NASM并不需要它。它可以毫无错误地汇编这段代码:

    mov  eax, [nane]
    mov  [name], eax
    

    请注意,如果你 要包含一个类型修饰符(并且你总是可以,只是为了显式),那么它不应该放在你最初拥有它的地方。汇编程序已经知道EAX寄存器的大小为DWORD。正确(显式)形式将是:

    mov  eax, dword [nane]
    mov  dword [name], eax
    

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

    另见答案:When should I use size directives in x86?