在 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]VAROFFSET VAR 之间的区别,请尝试逐步执行此代码:

.DATA
VAR DWORD 77

.CODE
    MOV EAX, VAR
    MOV EBX, OFFSET VAR
    MOV ECX, [VAR]
    MOV EDX, OFFSET [VAR]

你会清楚地看到不同。