我是装配新手,我正在使用MASM。 我看到这些代码行,并想知道
之间有什么区别a) push myVar
b) push [myVar]
c) push OFFSET myVar
我如何知道他们是否正在推动myVar的价值或地址 谢谢!
祝你好运, 感谢
答案 0 :(得分:3)
这取决于您使用的汇编程序。使用MASM / TASM,前两个变体执行相同的操作(将myVar
的值推送到堆栈上),而第三个变体将myVar
的地址推送到堆栈上(在分段模式下将是当前段内的偏移量。)
换句话说,MASM / TASM假定您要取消引用变量的有效地址,即使您在没有括号的情况下编写变量也是如此。如果你有一个立即值作为地址/操作数,那么会有所不同:
pushd 0 ; push the dword value 0 onto the stack
push dword ptr [0] ; push the dword at address 0 onto the stack
; will likely crash your program
与寄存器操作数相似:
push eax ; push the value of eax onto the stack
push dword ptr [eax] ; push the value at the address that eax points to
使用NASM,您可以将前两个变体写为
push dword [myVar] ; assuming a dword variable
第三个是
push myVar
答案 1 :(得分:2)
push myVar
只是将你的var推到堆栈上。
push [myVar]
取消引用您的var。如果myVar是一个指针,这段代码将推送堆栈上地址的值。
我不确定最后一个,但似乎反过来,push OFFSET myVar
正在推动堆栈上myVar
的地址。
答案 2 :(得分:1)
假设我们的data
段声明如下:
.data
myVar DWORD 1, 5, 9
没有[]
现在让我们把它放在code
部分:
.code
mov eax, myVar
如果我们现在看看寄存器(例如通过调试器),我们可以看到这样的事情:
EAX = 00000001
使用[]
我们可以使用括号作为解除引用运算符,就像我们在C中使用*
一样,所以如果我们现在将行更改为:
mov eax, [myVar]
我们得到:
EAX = 00000001
嗯......同样的。
但是现在我们可以想一想,如果将地址偏移到myVar
,我应该从myVar“array”获取下一个值:
mov eax, [myVar + 4] ; +4, because we have a DWORD (4 Bytes)
结果是:
EAX = 00000005
有效!但是,如果我没有括号做同样的事情会怎么样?
mov eax, myVar + 4
EAX = 00000005
嗯,同样的事情!因此使用这两种符号必须没有区别。所以它们完全等同。