push myVar,push [myVar]和push OFFSET myVar之间的区别

时间:2013-05-17 08:22:07

标签: assembly reverse-engineering masm

我是装配新手,我正在使用MASM。 我看到这些代码行,并想知道

之间有什么区别
a) push myVar

b) push [myVar]

c) push OFFSET myVar

我如何知道他们是否正在推动myVar的价值或地址 谢谢!

祝你好运, 感谢

3 个答案:

答案 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
嗯,同样的事情!因此使用这两种符号必须没有区别。所以它们完全等同。