一、Call与Invoke
可以简单地认为 INVOKE 是一个有参数类型检查的调用语句。当调用方法参数或参数类型不正确时,通过INVOKE可以在编译起发现错误,而通过CALL可能只有在运行期才能发现;所以建议用 INVOKE 指令而不是CALL去调用一个函数。
二、Addr与Offset
可以简单地认为 INVOKE 是一个有参数类型检查的调用语句。当调用方法参数或参数类型不正确时,通过INVOKE可以在编译起发现错误,而通过CALL可能只有在运行期才能发现;所以建议用 INVOKE 指令而不是CALL去调用一个函数。
二、Addr与Offset
- 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 的正确执行了。
三、Include与Includelib
Include:跟在其后的文件名所指定的文件在编译时将“插”在该处。当MASM处理到语句 include \masm\include\windows.inc 时,它就会打开文件夹\MASM32\include 中的文件windows.inc,这和您把整个文件都粘贴到您的源程序中的效果是一样的。
Includelib :和 include 不同,它仅仅是告诉编译器您的程序引用了哪个库。当编译器处理到该指令时会在生成的目标文件中插入链接命令告诉链接器链入什么库。