匯編語言-10CALL和RET指令


call和ret指令都是轉移指令,它們都修改IP,或同時修改CS和IP。它們經常被共同用來實現子程序的設計。

ret和retf

ret指令用棧中的數據,修改IP的內容,從而實現近轉移;
retf指令用棧中的數據,修改CS和IP的內容,從而實現遠轉移。

用匯編語法來解釋ret和retf指令

call指令

CPU執行call指令時,進行兩步操作:

(1)將當前的IP或CS和IP壓入棧中;
(2)轉移。

call指令不能實現短轉移,除此之外,call指令實現轉移的方法和jmp指令的原理相同。

依據位移進行轉移的call指令

call 標號(將當前的lP壓棧后,轉到標號處執行指令)

16位位移=標號處的地址-call指令后的第一個字節的地址;

16位位移的范圍為-32768 ~ 32767,用補碼表示;

16位位移由編譯程序在編譯時算出。

轉移的目的地址在指令中的call指令

"call far ptr 標號“實現的是段間轉移。

用匯編語法來解釋此種格式的call指令

轉移地址在寄存器中的call指令

指令格式:call 16 位reg

 

 用匯編語法來解釋此種格式的call指令

轉移地址在內存中的call指令

call word ptr 內存單元地址

例如

call dword ptr 內存單元地址

例如

call和ret的配合使用

call 標號會先將cs和ip壓入棧然后再跳轉,ret先將ip從棧中pop出然后轉移到ip。

mul指令

mul是乘法指令

(1)兩個相乘的數:兩個相乘的數,要么都是8位,要么都是16位。如果是8位,一個默認放在AL中,另一個放在8位reg或內存字節單元中;如果是16位,一個默認在AX中,另一個放在16位reg或內存字單元中。
(2)結果:如果是8位乘法,結果默認放在AX中;如果是16位乘法,結果高位默認在DX中存放,低位在AX中放。

格式如下:

mul reg
mul 內存單元

內存單元可以用不同的尋址方式給出

 

計算100*10

 

計算100*10000

模塊化程序設計

call與ret指令共同支持了匯編語言編程中的模塊化設計。在實際編程中,程序的模塊化是必不可少的。因為現實的問題比較復雜,對現實問題進行分析時,把它轉化成為相互聯系、不同層次的子問題,是必須的解決方法。而call與ret指令對這種分析方法提供了程序實現上的支持。利用call和ret指令,我們可以用簡捷的方法,實現多個相互聯系、功能獨立的子程序來解決一個復雜的問題。

參數和結果傳遞的問題

子程序一般都要根據提供的參數處理一定的事務,處理后,將結果(返回值)提供給調用者。其實,參數和返回值傳遞的問題,實際上就是如何存儲子程序需要的參數和產生的返回值的問題。

這里面就有兩個問題:

(1) 將參數N存儲在什么地方?
(2) 計算得到的數值,存儲在什么地方?

根據提供的N,來計算N的3次方

很顯然,可以用寄存器來存儲,可以將參數放到bx中;因為子程序中要計算N*N*N,可以使用多個mul指令,為了方便,可將結果放到dx和ax中。

 

用寄存器來存儲參數和結果是最常使用的方法。對於存放參數的寄存器和存放結果的寄存器,調用者和子程序的讀寫操作恰恰相反;調用者將參數送入參數寄存器,從結果商存器中取到返回值;子程序從參數寄存器中取到參數,將返回值送入結果寄存器。

計算data段中第一組數據的3次方,結果保存在后面一組dword單元中

批量數據的傳遞

將批量數據放到內存中,然后將它們所在內存空間的首地址放在寄存器中,傳遞給需要的子程序。對於具有批量數據的返回結果,也可用同樣的方法。

將一個全是字母的字符串轉化為大寫

這個子程序需要知道兩件事,字符串的內容和字符串的長度。因為字符串中的字母可能很多,所以不便將整個字符串中的所有字母都直接傳遞給子程序。但是,可以將字符串在內存中的首地址放在寄存器中傳遞給子程序。因為子程序中要用到循環,我們可以用loop指令,而循環的次數恰恰就是字符串的長度。出於方便的考慮,可以將字符串的長度放到cx中。

 

除了用寄存器傳遞參數外,還有一種通用的方法是用棧來傳遞參數

寄存器沖突的問題

功能:將一個全是字母,以0結尾的字符串,轉化為大寫。

assume cs:code

data segment
    db 'word',0
    db 'unix',0
    db 'wind',0
    db 'good',0
data ends

code segment

    start:mov ax,data
      mov ds,ax
      mov bx,O
      mov cx,4
      s:mov si,bx
      call capital
      add bx,5
      loop s
      mov ax,4c00h
      int 21h
      
    capital:push cx    ;先將外循環要用到的cx和si入棧
      push si
    change:mov cl,[si]
      mov ch,0
      jcxz ok
      and byte ptr [si],11011111b
      inc si
      jmp short capital
    ok:pop si    ;結束調用時從棧中把數據恢復到si和cx
      pop cx
      ret
    
code ends

end start

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM