一、Call與Invoke
可以簡單地認為 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 不同,它僅僅是告訴編譯器您的程式引用了哪個庫。當編譯器處理到該指令時會在產生的目標檔案中插入連結命令告訴連結器鏈入什麼庫。