MASM中的向前引用(Forward Reference)

  當程序需要引用尚未定義的變量或標號時,編譯器會如何處理呢,這就涉及到向前引用(Forward Reference)的概念。

  一、Forward Reference的概念

  程序引用到之前尚未定義的變量(Variable)、標號(Label)、段(Segment)或其他標識符(Symbol),編譯器會如何處理?MASM編譯器對源碼執行兩遍掃描,編譯器第一遍會假設該引用的類型,爲該類型留出存儲空間,然後在第二遍將該引用的地址或數據填充正確。

  這裏就會產生2個問題:

  1、編譯器假設的類型與實際類型不一致,會導致預留的空間太大或太小,太大會使程序變大或導致執行效率降低,太小則無法正常編譯通過。如jmp target,target默認假設爲near,編譯器預留空間爲3個字節;但實際target爲far,則需要5個字節。

  2、編譯器在處理前置引用時會降低編譯效率,因此儘量不要發聲向前引用。

  二、向前引用標號(Label)

jmp target;Forward Reference
...
...
target:

  1、指令跳轉,編譯器會假設jmp爲near jmp,如果jmp是short或far,需要明確指定,如far ptr。

  2、子程序調用,編譯器會假設call myproc爲near(無論子程序是通過proc還是label的方式定義),如果proc定義爲far,則需明確指定類型:call far ptr myproc。

  3、如果標號爲外部extrn引入,則不需要指定類型,直接jmp target或call myproc即可。

  三、向前引用變量(Variable)

  1、變量引用無論是否爲向前引用,都需要明確類型,只是數據段寄存器無法確定。編譯器會假設段寄出去爲:DS,可通過段前綴進行指定:ES:myvar。

  2、如果是segname:myvar或groupname:myvar的引用形式,且該段也未提前定義,則需將段加入到某個組(group)中,讓編譯器知道該段或組確實存在。

  四、注意事項

  1、.386代碼模式中,條件轉移指令(如jl、jb等)和far jmp與.286及之前,所佔用的字節數不一致,即在386代碼模式中,條件轉移指令不再限制爲short jmp(注意.386與.model的順序)。

  2、如果不是向前引用,jmp short和jmp near不用區分,編譯器會根據實際情況判斷,因此只需要jmp target即可,跨段跳轉才需要明確指定jmp far ptr target。

  3、proc如果不是向前引用,只需call myproc即可,不區分near和far,編譯器會自動判斷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章