为什么在 NASM 中我们必须使用方括号 ([]) 来 MOV 到内存位置?

Ped*_*ari 4 assembly nasm yasm

例如,如果我有一个名为 test 的变量,声明如下:

test db 0x01      ;suppose the address is 0x00000052
Run Code Online (Sandbox Code Playgroud)

如果我做这样的事情:

mov rax, test     ;rax = 0x00000052
mov rax, [test]   ;rax = 0x01
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试保存它时,如果我们遵循相同的模式:

mov test, 0x01    ;address 0x00000052 = 0x01
mov [test], 0x01  ;address 0x01 = 0x01
Run Code Online (Sandbox Code Playgroud)

但实际上是:

mov [test], 0x01  ;address 0x00000052 = 0x01
Run Code Online (Sandbox Code Playgroud)

那么,为什么方括号的行为取决于它们是第一个还是第二个操作数?

小智 5

在大多数汇编程序中,使用方括号取消引用内存位置。您将该值视为内存地址。

例如,让我们以此为例。

mov ax, [0x1000]
Run Code Online (Sandbox Code Playgroud)

这将获得 0x1000 处的值并将其放入 AX。如果删除方括号,则只移动 0x1000。

如果您将一个值移动到一个数字,您就是将它放入该值(内存位置)中。

如果您是 C 开发人员,这里有一个示例问题。

如果您被其他人欺负学习 C,称您为“巨魔”,请不要让这个例子惹恼您。

如果你愿意,你可以忽略它,但scanf()如果你知道 C,你可能已经知道了。

int a = 10;
scanf("%d", a);
Run Code Online (Sandbox Code Playgroud)

现在,这是一个非常常见的错误,因为我们没有获得变量的内存地址。相反,我们使用它的值作为地址。该scanf()功能要求您提供地址。

如果我们这样做,

scanf("%d", &a);
Run Code Online (Sandbox Code Playgroud)

我们将获得变量 a 的地址。

  • 关键是 MASM 是奇怪的/不一致的,即使它*没有*有括号,也通过使`mov eax,symbol`成为负载。要确定它是加载还是 mov-immediate,您必须查看它是定义为 `equ` 或 `=` 常量还是定义为标签。NASM 强制您使用与您定义名称的方式相匹配的语法,因此您始终可以分辨出它是哪种指令。 (3认同)