这是我写过的代码的一部分:
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
我有两个问题:
有没有办法不使用EAX
寄存器将 nane 变量的值移动到 name 变量?
为什么我们需要使用类型修饰符?
答案 0 :(得分:7)
不,只使用一条指令就无法做到这一点。也就是说,你不能这样做:
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
几乎是总是一个更好的主意。
类型修饰符应该不。事实上,NASM并不需要它。它可以毫无错误地汇编这段代码:
mov eax, [nane]
mov [name], eax
请注意,如果你 要包含一个类型修饰符(并且你总是可以,只是为了显式),那么它不应该放在你最初拥有它的地方。汇编程序已经知道EAX
寄存器的大小为DWORD
。正确(显式)形式将是:
mov eax, dword [nane]
mov dword [name], eax
但是,正如我所说,这实际上并不是必需的。汇编程序可以告诉它在DWORD
地址处存储name
大小的值,因为源操作数(EAX
)本身是DWORD
- 大小。