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