2

我是组装新手,我正在使用 MASM。我看到这些代码行,想知道它们之间有什么区别

a) push myVar

b) push [myVar]

c) push OFFSET myVar

我怎么知道他们是否在推送 myVar 的值或地址 谢谢!

最好的问候,谢谢

4

3 回答 3

4

push myVar只是将您的 var 推入堆栈。

push [myVar]正在取消引用您的 var。如果 myVar 是一个指针,此代码将把值压入栈中的地址。

我不确定最后一个,但它似乎是相反的,push OFFSET myVar将地址推myVar入堆栈。

于 2013-05-17T08:27:05.160 回答
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
于 2013-05-17T08:48:57.630 回答
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

嗯,一样的!因此,使用这两种表示法一定没有区别。所以它们是完全等价的。

于 2014-02-08T12:10:33.830 回答