使用 GCC,为 32 位 Intel 架构编译,带有.intel_syntax noprefix
. 假设我有以下.data
部分:
A: .int 0x1, 0x2
当用作操作数时,以下各项有什么区别:A
, [A]
, offset A
? [..]
另外,在寄存器和内存标签上使用时有什么区别?
这里很好地[..]
回答了简单编写寄存器和放入寄存器之间的区别。
使用 GCC,为 32 位 Intel 架构编译,带有.intel_syntax noprefix
. 假设我有以下.data
部分:
A: .int 0x1, 0x2
当用作操作数时,以下各项有什么区别:A
, [A]
, offset A
? [..]
另外,在寄存器和内存标签上使用时有什么区别?
这里很好地[..]
回答了简单编写寄存器和放入寄存器之间的区别。
让我给你一个简短的解释。
[] 括号的意思是“不要使用内容,而是使用地址”。当使用带标签的 DATA 时,您可以省略它们(这取决于您的汇编器的语法,但在 MASM 中它肯定是这样工作的)。为什么?无法直接处理内存中的数据;相反,您只需处理内存中某处的数据(在某个地址上)。因此,不会发生歧义,您始终使用地址数据。当您将它们与寄存器一起使用时,情况就完全不同了:
MOV EAX, 10
只需在 EAX 寄存器中加载 10 (0x0000000A)。您直接使用收银机。但:
MOV EAX, 666
MOV BYTE PTR [EAX], 77
将 77 加载到内存地址 666。该BYTE PTR
指令是必需的,因为汇编程序不知道它是否应该使用 1、2、4 等字节。上面写着“[EAX]
不要使用 EAX,而是使用 EAX 中包含的地址(内存位置)。
如果您想找出 和 之间的区别,[VAR]
请尝试逐步执行此代码:VAR
OFFSET VAR
.DATA
VAR DWORD 77
.CODE
MOV EAX, VAR
MOV EBX, OFFSET VAR
MOV ECX, [VAR]
MOV EDX, OFFSET [VAR]
你会清楚地看到差异。