彙編語言——過程

過程定義由PROC與ENDP僞指令實現,形式如下:
 過程名 PROC    [NEAR|FAR]
  <過程體>
 過程名   ENDP
      過程名在整個程序中必須是唯一的。
      過程名本質上與標號一樣,也具有3種屬性:段地址、偏移地址和類型(NEAR或FAR)。
       PROC後用關鍵字NEAR、FAR或空,以表示過程的類型(缺省爲NEAR)。
1.過程調用和返回指令
(1)CALL:過程調用
 與JMP指令類似,CALL指令包括下列4種調用方式:
 段內直接調用(Intrasegment/Direct Call)
 段間直接調用(Intersegment/Direct Call)
 段內間接調用(Intrasegment/Indirect Call)
 段間間接調用(Intersegment/Indirect Call)
  段內調用在同一代碼段內進行,又稱近(Near)調用;
  段間調用可以在不同代碼段之間進行,又稱遠(Far)調用。
語法格式:
 CALL  ProcName ; 若ProcName與該指令在同一代碼段,則爲段內直接調用:
   ;  IP進棧,IP = label的偏移地址;
   ; 若ProcName與該指令不在同一代碼段,則爲段間直接調用:
   ;  CS:IP 進棧,CS:IP = label的分段地址
 CALL reg16/mem16 ; 段內間接調用:IP進棧,IP = reg16 / [mem16]
 CALL mem32 ; 段間間接調用:
   ; CS:IP 進棧,CS = mem32高字,IP = mem32低字
功能描述:
    (1)返回地址進棧。
 遠調用:CS與IP(下一條指令的地址)依次進棧。
 近調用:IP(下一條指令的16位偏移地址)進棧。
    (2)轉移到過程的第1條指令去執行。
 遠調用:根據操作數,將32位分段地址送CS:IP。
 近調用:根據操作數,將16位偏移地址送IP。
對標誌位的影響:無。
(2)RET指令RET(Return):過程返回
        過程返回分爲近(段內)返回和遠(段間)返回。
        語法格式:
 RET  ; 近返回或遠返回
 RET imm16   ; 近返回或遠返回,並調整堆棧:SP = SP + imm16
        功能描述:
      RET:返回地址出棧,從而實現轉移到返回地址處。其中,
  遠返回:POP 1個雙字到CS:IP。
  近返回:POP 1個字到IP。
      RET imm16:在返回地址出棧後,CPU立即將imm16加到堆棧指針SP。這種機制用來在返回前將參數從棧中移出。
        對標誌位的影響:無。
        說明:RET由彙編器根據其所在過程的類型(NEAR或FAR)決定是近返回還是遠返回。缺省爲近返回。
*使用過程應注意的問題
 在過程體內必須有一條RET指令被執行到。如果在過程內沒有執行到RET或其它轉移指令,程序將繼續執行ENDP後的指令。
 正確選擇過程的類型。通常基於下列原則:
 若過程只在同一代碼段中被調用,則定義爲NEAR。
 若過程可以在不同代碼段中被調用,則定義爲FAR。
 CALL與RET的類型要一致。
 通常要保證RET指令執行前,棧頂內容正好是返回地址。
 注意保護相關寄存器的值。通常,除了作爲返回參數的寄存器外,過程不應改變其它寄存器的值。
 可以將過程定義放在單獨的代碼段中。若過程定義與主程序處於同一代碼段,則要保證其只有被調用時,纔會執行。
 對於大多數過程,需要與調用者之間傳遞一定數量的數據,即參數。根據傳遞的方向,將參數分爲兩類:
 入口參數:由調用者向過程傳遞的數據,作爲過程的輸入參數。
 出口參數:由過程向調用者返回的數據,作爲過程的輸出參數。
 根據問題的需要,過程可以只有入口參數或只有出口參數,也可以二者兼有。
 對於過程與調用者之間的參數傳遞,可根據傳遞的數據量,選擇採用寄存器、變量或堆棧等方式。由於過程是相對獨立的功能塊, 因此,在定義過程時,通常要加上適當的註釋,主要包括功能、入口參數與出口參數等。

1 用變量傳遞參數  
在程序中定義全局變量,如放在數據段,過程直接按名訪問該變量。
  過程直接以變量作爲參數,雖然方便,但通用性較差。
2 用寄存器傳遞參數  
通過寄存器傳遞數據或數據地址。
  通常選擇AL、AX、DX:AX(或EAX)傳遞字節、字或雙字。
  傳遞16位偏移地址最好選擇SI、DI或BX,
  傳遞32位分段地址可以用DS:BX、DS:SI、DS:DI、ES:BX、ES:SI或ES:DI等。
  當然,要根據需要來選擇,以方便爲主,但很少使用BP來傳遞參數。
3 用地址表傳遞參數  
建立一個地址表,存放所有參數的地址,傳遞地址表的首地址給過程。
     這種方法特別適合於參數較多的情況。
4 用堆棧傳遞參數  
    調用者通過調整堆棧指針爲返回參數預留空間,然後將過程所需的入口參數進棧;
    過程從堆棧得到入口參數,返回前將出口參數寫入堆棧;
    調用者通過出棧得到返回參數。
    過程從堆棧存取參數時,通常使用BP,因爲其隱含的段地址在SS中。
   採用堆棧傳遞參數時,典型的過程結構如下:
 StdProc proc near
              push     bp
             mov     bp, sp  ; BP指向當前棧頂,用於取入口參數
          ...
             pop      bp
             ret      ParmSize  ; 返回前從堆棧移出入口參數
 StdProc      endp
        其中,ParmSize是過程被調用前進棧的入口參數的字節數。
5 用代碼流傳遞參數  
由位於CALL指令之後的代碼流(Code Stream)傳遞參數。
 

遞歸過程   
1.遞歸過程的主要思想
 將一個問題分解爲幾個子問題,而其中的有些子問題與原問題相同,只是規模要小。
 隨着問題的不斷分解,一定存在一個與原問題相同的最小問題,可以直接解決,這便是遞歸出口。
2.遞歸過程設計的關鍵
 保證除了出口參數外,每次調用都不破壞以前調用時所用到的參數和中間結果。
 遞歸過程的參數傳遞常使用堆棧,也可使用寄存器,但通常不用變量。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章