例如,如果我有一个名为test的变量声明为:
test db 0x01 ;suppose the address is 0x00000052
如果我这样做:
mov rax, test ;rax = 0x00000052
mov rax, [test] ;rax = 0x01
但是,当我尝试保存时,如果我们遵循相同的模式:
mov test, 0x01 ;address 0x00000052 = 0x01
mov [test], 0x01 ;address 0x01 = 0x01
但实际上是:
mov [test], 0x01 ;address 0x00000052 = 0x01
那么,为什么方括号的行为会有所不同,这取决于它们是第一个还是第二个操作数?
答案 0 :(得分:4)
在大多数汇编程序中,使用方括号取消引用内存位置。您将该值视为内存地址。
例如,我们以此为例。
mov ax, [0x1000]
这将获得0x1000的值并将其放入AX。如果删除方括号,则只移动0x1000。
如果将值移动到某个数字,则将其置于值(内存位置)。
如果你被其他人欺负学习C,称你为“巨魔”,不要让这个例子惹恼你。
如果您愿意,可以忽略此项,但如果您了解C,则可能知道scanf()
。
int a = 10;
scanf("%d", a);
现在,这是一个非常常见的错误,因为我们没有得到变量的内存地址。相反,我们使用其值作为地址。 scanf()
功能要求您提供地址。
如果我们这样做,
scanf("%d", &a);
我们将获得变量a的地址。
答案 1 :(得分:1)
史蒂夫·伍兹(Steve Woods)的帖子给我的印象是他认为&是取消引用运算符。 &是C的引用运算符。 *是C的解除引用运算符。 OP确实存在担忧。 []似乎可以同时发挥作用,具体取决于上下文。它既不是取消引用运算符也不是引用运算符。它是“这是一个内存地址!!!”运算符。
https://nasm.us/doc/nasmdoc3.html#section-3.3
有效地址是引用内存的指令的任何操作数。在NASM中,有效地址的语法非常简单:它们由一个表达式评估为所需的地址,并用方括号括起来。
; assume wordvar was used as a label, and the linker gave it address 6291668
; or mostly equivalently, you used wordvar equ 6291668
mov eax,wordvar ; eax = 6291668. Move value 6291668 to eax.
mov eax,[wordvar] ; eax = 12. Move contents of address 6291668 to eax.
mov eax,13
; mov wordvar,eax ; Move eax to value 6291668. syntax error.
mov [wordvar],eax ; mem(6291668) = 13. Move eax to address 6291668.
当操作数是内存地址时,必须将其括在方括号中以告知nasm这种情况。这不是取消引用它,只是让nasm知道发生了什么。如果与取消引用运算符等效,则
mov [wordvar], eax
将内存位置12设置为13。
它不是取消引用运算符。这是“这是一个内存地址”运算符。这似乎在不同情况下都是取消引用和引用,因为x86和x86_64指令根据其操作数是内存位置还是值而表现不同。我正在自学汇编程序,必须自己解释一下。