[遇到问题时,我正在尝试NASM汇编程序:
mov (sp),bx
mov [sp],bx
第一条指令正确组装,而第二条指令没有正确组装,并给我错误:
错误:无效的有效地址
为什么?两者有什么区别?
(%sp)
将是AT&T语法寻址模式。 (无效,因为16位寻址模式不能直接使用SP,只能使用BP|BX + SI|DI
NASM x86 16-bit addressing modes;这也是mov [sp], bx
无效的原因。)
在NASM语法中,方括号[]
表示内存操作数。
[在NASM中,SP周围的括号()
被删除,就像任何编译时表达式一样,所以mov (sp), bx
组装为89DC mov sp,bx
。通过组装并在输出上使用ndisasm
自己尝试。 (或汇编为-felf32
并使用objdump
)
这是两个寄存器之间的移动,将覆盖堆栈指针。很有可能不是您想要的,并且与使用mov [bp], bx
或其他内容存储到内存中完全不同。
[在NASM中,当编写类似mov ax, (1+3) * 4
的代码时,您可能会使用parens,因此NASM的表达式解析器将处理parens,并且显然在parens中具有寄存器名称不会更改任何内容。
我仅在此答案的顶部提到AT&T语法,因为那和Plan9 / Go语法是通常唯一一次将寄存器名称放入parens中的时间; NASM语法令人困惑;不要这样做。