假设我声明了以下内容:
section .bss
buffer resb 1
这些说明如下:
mov al, 5
mov [buffer], al
mov bl, [buffer]
mov cl, buffer
我是否理解bl将包含值5,而cl将包含变量buffer
的内存地址?
我对
之间的差异感到困惑mov cl, buffer
vs mov cl, [buffer]
更新:阅读回复后,我认为以下摘要是准确的:
假设array resb 0
下存在声明section .bss
。我的理解是:
mov edi, array
将第0个数组索引的内存地址放在edi
中。mov [edi], 3
将VALUE 3放入数组的第0个索引add edi, 3
之后,edi
现在包含数组第3个索引的内存地址mov al, [array]
将数据放在第0个索引中al
。mov al, [array+3]
将第三个索引的DATA放入al
。mov [al], [array]
无效。mov array, 3
无效,因为你不能说“嘿,我不喜欢array
存储的偏移,所以我称之为3”mov [array], 3
将值3放入数组的第0个索引中。请提及是否有任何错误。
答案 0 :(得分:20)
方括号基本上像解除引用运算符一样工作(例如,像C中的*
)。
所以,像
mov REG, x
将x
的值移至REG
,而
mov REG, [x]
将x
指向的内存位置的值移动到REG
。请注意,如果x
是标签,则其值是该标签的地址。
至于你的问题:
我理解bl将包含值5和cl 将包含变量缓冲区的内存地址?
是的,你是对的。但请注意,由于CL
只有8位宽,因此它只包含buffer
地址的最低有效字节。
答案 1 :(得分:13)
确实,你的想法是正确的。也就是说,bl将包含5和cl缓冲区的内存地址(实际上标签缓冲区本身就是一个内存地址)。
现在,让我解释一下你提到的操作之间的差异:
可以使用mov reg,imm
将立即数移入寄存器。可能令人困惑的是,缓冲区等标签本身就是包含地址的立即值。
您无法真正将寄存器移动到立即数,因为立即数值是常量,如2
或FF1Ah
。您可以做的是将寄存器移动到常量点的位置to.You可以像mov [const], reg
。
您还可以使用mov reg2,[reg1]
等间接寻址,将reg1指向有效位置,并将reg1指向的值传输到reg2。
因此,mov cl, buffer
会将缓冲区的地址移动到cl(可能会也可能不会提供正确的地址,因为cl只有一个字节长),而mov cl, [buffer]
将得到实际值。
F5B1
,那么[a]指的是 RAM中的地址F5B1 F5B1
等值。答案 2 :(得分:4)
你明白了。但是,有一些细节值得铭记:
cl
为8位,cx
为16位,ecx
为32位,{{1}是64位)。因此,rcx
可能与变量cl
的地址不相等。它只有地址的最低8位。buffer
的中断例程或线程,则buffer
中的值可能与5不同。中断例程实际上可能会影响任何寄存器失败保留寄存器值。答案 3 :(得分:2)
对于使用立即值作为操作数将所有值写入ram位置(或用于计算内部)的所有指令,我们必须指定我们想要访问的字节数。因为我们的汇编不知道我们是否只想访问一个字节,一个字,或一个 doppleword ,例如,如果立即值较低值,如下面的说明所示。
array db 0FFh, 0FFh, 0FFh, 0FFh
mov byte [array], 3
结果:
array db 03h, 0FFh, 0FFh, 0FFh
...
mov word [array], 3
结果:
array db 03h, 00h, 0FFh, 0FFh
...
mov dword [array], 3
结果:
array db 03h, 00h, 00h, 00h
德克