汇编语言ret (call与recall在汇编语言的区分)

什么是call?

在我们平时编程过程中,都会用到函数或子程序,反汇编就是call指令 。可以使程序跳转到指定代码段,履行结束后,返回主程序继续向下履行。

分析如下代码段,程序履行后,ax寄存器中的数值为多少?

汇编指令ret详解,汇编语言中hlt用法

首先,mov ax,0履行结束后,ax寄存器中的值为0,该指令机器码长度为3字节,因此,ip=3。

call far ptr s履行后,程序会跳转到标号s处,但是需求将该指令的下一条指令地址保存起来,s段履行后要返回。因此push cs=1000,push ip=8。再跳转cs=1000,ip=9。

pop ax履行后,ax=8h;

add ax,ax履行后,ax=10h;

pop bx履行后,bx=1000h;

add ax,bx履行后,ax=1010h;

因为s没有返回,最终ax寄存器中的值为1010h。

call 寄存器

call后面不仅可以加标号,也可以直接加寄存器。

汇编指令ret详解,汇编语言中hlt用法

call ax履行后,将下一条指令inc ax的偏移地址ip入栈,因此sp指向的内存中数据为5。然后ip=6;

mov bp,sp履行后,bp指向的内存空间数据也为5;

add ax,[bp]履行后,相当于ax=ax+5=11,即0bh。

转移地址在内存中的call指令

语法:call word ptr 内存单元地址

相当于:

push IP
jmp word ptr内存单元地址

履行如下指令:

mov sp,10h
mov ax,0123h
mov ds:[0],ax
call word ptr ds:[0]

最终跳转到ds:[0]=0123h,(IP)=0123H,SP=0EH(10H-2H=0EH)。

语法:call dword ptr 内存单元地址

相当于:

push CS
push IP
jmp dword ptr 内存单元地址

履行如下指令:

mov sp,10h
mov ax,0123h
mov ds:[0],ax
mov word ptr ds:[2],0
call dword ptr ds:[0]

履行后,ds中数据类型为dword,0-1的word类型数据为0123h,因此(IP)=0123h;2-3的word类型数据为0,因此(CS)=0,入栈dword类型是4个字节数据,(SP)=10h-4h=0ch。

浏览程序

分析如下程序,最终ax寄存器中的值为多少?(debug调试会因为中断问题造成和理论分析不一致)

汇编指令ret详解,汇编语言中hlt用法

首先,栈空间16个字节0,ss栈段为ax,ds数据段也是ax;

ax初始值为0;

当履行call时,首先将call下方第一个inc ax的IP入栈,(SP)=0EH,并跳转至ds:[0EH],这个值就是SP指向空间保存的IP,程序正常向下运行,inc ax履行三次,最终(ax)=03H。

ret指令

汇编指令ret详解,汇编语言中hlt用法

call指令履行时,将当前指令的下一条指令偏移IP保存入栈,然后跳转至标号处,也就是我们说的函数,函数履行完毕,ret指令会将IP弹出。

上述程序,call s履行三次add ax,ax,最终(ax)=8,然后返回至mov bx,ax,(bx)=08h。