call和ret指令用法
call和ret都是轉移指令,它們都可以修改IP或者同時修改CS:IP,它們被共同用來實現子程式的設計
ret和retf區別
ret是用棧中的資料修改IP的值,實現近轉移(段內轉移)
retf是用棧中的資料修改cs:IP的值,實現遠轉移(段間轉移)
1cpu執行ret時,執行以下操作
(IP)=((ss)*16+(sp))(sp)=(sp)+2
相當於pop ip
2cpu執行retf時,執行以下操作
(IP)=((ss)*16+(sp))(sp)=(sp)+2
(CS)=((ss)*16+(sp))(sp)=(sp)+2
相當於POP IP和POP CS
call指令:cpu執行call時執行以下操作
1將當前IP或CS和IP壓入棧中,PUSH IP 或者 PUSH IP PUSH CS
2轉移(jmp)
call不能實現段內短轉移(就是jmp short),除此之外,call實現轉移方法和jmp原理相同
ccall標號 功能:將當前IP壓棧後,轉到標號處執行
cpu執行call時,執行以下操作、
1 (sp)=(sp)-2 ((ss)*16+(sp))=(ip)
相當於 push ip
2(IP)=(IP)+16位位移
相當於jmp near ptr 標號
注意:壓棧的IP是call指令的下一條指令(參考cpu執行指令的過程,指令放入緩衝區,cpu指向下一條指令)
實驗如下程式證明:
assume cs:code
code segment
start:mov ax,0
call S
inc ax
S:pop ax
add ax,ax
pop bx
mov ax,4c00h
int 12h
code ends
end start
程式如圖:
pop ax時 ax的值是0006,ip=0006時是inc ax的指令
call far ptr 標號 功能:將當前CS和IP壓棧
cpu執行這種格式的call指令時執行以下操作
1(sp)=(sp)-2 ((ss)*16+(sp))
相當於 push cs
(sp)=(sp)-2 ((ss)*16+(sp))=(ip)
相當於pus ip
2(cs)=標號所在的段地址(cs)(IP)=標號所在的偏移地址(IP)
相當於jmp far ptr 標號
call 16位暫存器 功能:將當前ip入棧,ip=16位暫存器
cpu執行這種格式的call指令時執行以下操作
1 (ip)=(sp)-2 ((ss)*16+(sp))=(ip)
相當於 puship
2(ip)=(16位暫存器)
相當於jmp 16位暫存器
callword ptr 記憶體單元地址
彙編解釋:1 push ip2 jmp word ptr 記憶體單元地址(ip=記憶體單元的資料)
calldword ptr 記憶體單元地址
彙編解釋:1 push cspush ip2jmp
dword ptr 記憶體單元地址(cs=記憶體單元高位的資料 ip=記憶體單元低位的資料)記憶體單元地址cs放在高位地址,ip放在地位地址
一個具有一定功能的程式段為子程式(函式),在需要的時候用call執行,用ret返回,call對應ret
實現程式如下:
assume cd:code
data segment
db 'ILoveProgramming'
data ends
code segment
start:mov ax,data
mov ds,ax
mov si,0 ;用si指向資料的首地址
mov cx,16 ;資料長度16
call capital ;呼叫轉換字元大小的子程式
mov ax,4c00h
int 21h
capital:and byte ptr [si],11011111b
inc si
loop capital
ret ;迴圈結束後回到call指令的下一條指令繼續執行
code ends
end start