一文详解汇编语言call和ret指令
在我们平时编程过程中,都会用到函数或子程序,反汇编就是call指令。可以使程序跳转到指定代码段,执行结束后,返回主程序继续向下执行。
什么是call?
在我们平时编程过程中,都会用到函数或子程序,反汇编就是call指令。可以使程序跳转到指定代码段,执行结束后,返回主程序继续向下执行。
(资料图片)
分析如下代码段,程序执行后,ax寄存器中的数值为多少?
首先,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后面不仅可以加标号,也可以直接加寄存器。
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 IPjmp word ptr 内存单元地址
执行如下指令:
mov sp,10hmov ax,0123hmov ds:[0],axcall word ptr ds:[0]
最终跳转到ds:[0]=0123h,(IP)=0123H,SP=0EH(10H-2H=0EH)。
语法:call dword ptr 内存单元地址
相当于:
push CSpush IPjmp dword ptr 内存单元地址
执行如下指令:
mov sp,10hmov ax,0123hmov ds:[0],axmov word ptr ds:[2],0call 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调试会因为中断问题造成和理论分析不一致)
首先,栈空间16个字节0,ss栈段为ax,ds数据段也是ax;
ax初始值为0;
当执行call时,首先将call下方第一个inc ax的IP入栈,(SP)=0EH,并跳转至ds:[0EH],这个值就是SP指向空间保存的IP,程序正常向下运行,inc ax执行三次,最终(ax)=03H。
ret指令
call指令执行时,将当前指令的下一条指令偏移IP保存入栈,然后跳转至标号处,也就是我们说的函数,函数执行完毕,ret指令会将IP弹出。
上述程序,call s执行三次add ax,ax,最终(ax)=8,然后返回至mov bx,ax,(bx)=08h。
关键词: