这是我编写的代码的一部分:
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)
我有两个问题:
有没有办法不使用EAX寄存器将nane变量的值移动到name变量?
为什么我们需要使用类型修饰符?
不,只使用一条指令就无法做到这一点.也就是说,你做不到:
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临时寄存器几乎总是一个更好的主意.
那里不应该要求类型修饰符.事实上,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指令?