八 汇编 CALL 和 RET 指令

call 和 ret 都是转移指令,都修改IP,或同时修改 CS和IP.
1.1 ret 和 retf
CPU在执行ret指令的时候,进行下面2步操作:
(IP)=((ss)*16+(sp))(sp)=(sp)+2
相当于进行pop IP.
举例:
ret指令执行后,(IP)=0; CS:IP指向代码段的第一条指令 。
CPU在执行retf指令的时候,进行下面4步操作:
(IP)=((ss)*16+(sp))(sp)=(sp)+2(CS)=((ss)*16+(sp))(sp)=(sp)+2
相当于:
pop IP
pop CS
举例:
retf指令执行之后,CS:IP指向代码段的第一条指令 。
1.2 call 指令
CPU执行call指令时,进行两步操作:
将当前的 IP 或 CS和IP 压入栈中 。(这是记录,为了能够回来 。)转移
1.2.1 依据位移进行转移的call指令

八  汇编  CALL 和 RET 指令

文章插图
格式:
【八汇编CALL 和 RET 指令】call 标号(将当前IP压栈后,转到标号处执行指令)
CPU执行如下操作:
1.(sp)=(sp)-2//栈向小伸展,腾出空间((ss)*16+(sp))=(IP)//将旧IP入栈,相当于 push IP2.(IP)=(IP)+16位位移//转移到新IP处,相当于 jmp near ptr 标号 。
1.2.2 转移的目的地址在指令中的call指令
格式:
call far ptr 标号实现段间转移
CPU执行如下操作:
1. (sp)=(sp)-2//栈向小生长,腾出空间((ss)*16+(sp))=(CS)//CS入栈,相当于,push CS(sp)=(sp)-2((ss)*16+(sp))=(IP)//IP入栈,相当于,push IP.对当前CS IP进行记录2. (CS)=标号所在段的段地址(IP)=标号所在段的偏移地址 //赋予新的CSIP,进行 jmp far ptr 标号
1.2.3 转移地址在寄存器中的call指令
格式:
call 16位reg
功能:
1.(sp)=(sp)-2((ss)*16+(sp)) = (IP) //入栈,记录旧IP ,相当于push IP2.(IP)=(16位reg)//赋予新IP,相当于 jmp 16位reg
1.2.4 转移地址在内存中的call指令
CPU相当于执行
push IPjmp word ptr 内存单元地址
举例:
mov sp,10hmov ax,0123hmov ds:[0],axcall word ptr ds:[0]
执行后:
八  汇编  CALL 和 RET 指令

文章插图
(IP) = 0123H
(sp)=0EH-->栈需要记录IP,需要向小生长空间,则sp=sp-2
CPU相当于执行:
push CSpush IPjmp dword ptr 内存单元地址
举例:
mov sp,10hmov ax,0123hmov ds:[0],axmov word ptr ds:[2],0call dword ptr ds:[0]
执行后,
(CS)=0,(IP)=0123H,
(sp)=0CH---->栈需要记录CS & IP,需要向小生长两次,sp=sp-2-2
1.3 call 和 ret 的配合使用
1.4 mul指令
mul乘法指令:
1.两个相乘的数,要么是8位,要么是16位:
2.结果:
格式:
mul reg
mul 内存单元
其中,内存单元可以用不同的寻址方式给出 。
mul byte ptr ds:[0] //含义:(ax)=(al)*((ds)*16+0)其中一个值默认在al中 。
mul word ptr [bx+si+8] //含义:(ax)=(ax)*((ds)*16+(bx)+(si)+8)结果的低16位;(dx)=(ax)*((ds)*16+(bx)+(si)+8)结果的高16位;