我是组装新手,我正在使用 MASM。我看到这些代码行,想知道它们之间有什么区别
a) push myVar
b) push [myVar]
c) push OFFSET myVar
我怎么知道他们是否在推送 myVar 的值或地址 谢谢!
最好的问候,谢谢
我是组装新手,我正在使用 MASM。我看到这些代码行,想知道它们之间有什么区别
a) push myVar
b) push [myVar]
c) push OFFSET myVar
我怎么知道他们是否在推送 myVar 的值或地址 谢谢!
最好的问候,谢谢
push myVar
只是将您的 var 推入堆栈。
push [myVar]
正在取消引用您的 var。如果 myVar 是一个指针,此代码将把值压入栈中的地址。
我不确定最后一个,但它似乎是相反的,push OFFSET myVar
将地址推myVar
入堆栈。
这取决于您使用的汇编程序。对于 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
假设我们的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
嗯,一样的!因此,使用这两种表示法一定没有区别。所以它们是完全等价的。