在 GAS .intel-syntax 程序集的内存标签和寄存器上使用 "offset" 和“[ ]”有什么区别?
What is the difference between using "offset" and "[ ]" on memory labels and registers in GAS .intel-syntax assembly?
使用 GCC,针对 32 位 Intel 架构进行编译,.intel_syntax noprefix
。
假设我有以下 .data
部分:
A: .int 0x1, 0x2
以下用作操作数时有什么区别:A
、[A]
、offset A
?
另外,[..]
用在寄存器和内存标签上有什么区别?
简单写入寄存器和将其放入 [..]
之间的区别here 回答得很好。
让我给你一个简单的解释。
[] 括号的意思类似于 "do not work with the content, but with the address"。
当使用带标签的 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 中包含的 ADDRESS(内存位置)。
如果您想找出 [VAR]
、VAR
和 OFFSET VAR
之间的区别,请尝试逐步执行此代码:
.DATA
VAR DWORD 77
.CODE
MOV EAX, VAR
MOV EBX, OFFSET VAR
MOV ECX, [VAR]
MOV EDX, OFFSET [VAR]
你会清楚地看到不同。
使用 GCC,针对 32 位 Intel 架构进行编译,.intel_syntax noprefix
。
假设我有以下 .data
部分:
A: .int 0x1, 0x2
以下用作操作数时有什么区别:A
、[A]
、offset A
?
另外,[..]
用在寄存器和内存标签上有什么区别?
简单写入寄存器和将其放入 [..]
之间的区别here 回答得很好。
让我给你一个简单的解释。
[] 括号的意思类似于 "do not work with the content, but with the address"。
当使用带标签的 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 中包含的 ADDRESS(内存位置)。
如果您想找出 [VAR]
、VAR
和 OFFSET VAR
之间的区别,请尝试逐步执行此代码:
.DATA
VAR DWORD 77
.CODE
MOV EAX, VAR
MOV EBX, OFFSET VAR
MOV ECX, [VAR]
MOV EDX, OFFSET [VAR]
你会清楚地看到不同。