offset 和 addr 之间有如下区别:
- addr不可以处理向前引用,offset则能。所谓向前引用是指:标号的定义是在invoke 语句之后,譬如在如下的例子:
invoke MessageBox,NULL, addr MsgBoxText,addr MsgBoxCaption,MB_OK
......
MsgBoxCaption db "Iczelion Tutorial No.2",0
MsgBoxText db "Win32 Assembly is Great!",0
如果您是用 addr 而不是 offset 的话,那 MASM 就会报错。 - addr可以处理局部变量而 offset 则不能。局部变量只是在运行时在堆栈中分配内存空间。而 offset 则是在编译时由编译器解释,这显然不能用offset 在运行时来分配内存空间。编译器对 addr 的处理是先检查处理的是全局还是局部变量,若是全局变量则把其地址放到目标文件中,这一点和 offset 相同,若是局部变量,就在执行 invoke 语句前产生如下指令序列:
lea eax, LocalVar
push eax
因为lea指令能够在运行时决定标号的有效地址,所以有了上述指令序列,就可以保证 invoke 的正确执行了。