call和ret指令都是转移指令,它们都修改IP,或同时修改CS和IP。它们一般用来实现子程序的设计。
10.1 ret和retf
ret指令用栈中的数据,修改IP的内容,从而实现近转移;
retf指令使用栈中的数据,修改CS和IP的内容,从而实现远转移。
10.2 call指令
CPU执行call指令时,进行两步操作:
(1)将当前的IP或CS和IP压入栈中;
(2)转移。
10.3 依据位移进行转移的call指令
call标号(将当前的IP压栈后,转到标号处执行指令)
注:注意,在执行指令时,IP是会在执行之前就改变的。
10.4 转移的目的地址在指令中的call指令
“call far ptr 标号” 实现的是段间转移。
先push cs
再push ip
最后转移
10.5 转移地址在寄存器中的call指令
指令格式:call 16 位reg
功能:
(sp)=(sp)-2
((ss)*16+(sp))=(ip)
(ip)=(16位reg)
10.6 转移地址在内存中的call指令
转移地址在内存中的call指令有两种格式。
(1)call word ptr 内存单元地址
push IP
jmp word ptr 内存单元地址
(2)call dword ptr 内存单元地址
push CS
push IP
jmp dword ptr 内存单元地址
CS在后一个内存单元中。
10.7 call和ret的配合使用
略 看书
注:pop后,栈里的值还是在的,只是sp不在指向那里了。
10.8 mul指令
mul是乘法指令,使用mul做乘法的时候,注意以下两点。
(1)两个相乘的数:两个相乘的数,要么都是八位,要么都是16位。如果是八位,一个默认放在AL中,另一个放在8位reg或内存字节单元中;如果都是16位,一个默认在AX中,另一个放在16位reg或内存单元中。
(2)结果:如果是八位乘法,结果默认放在AX中;如果是16位乘法,结果高位默认在DX中存放,低位在AX中存放。
10.9 ~10.11 略
10.12 寄存器冲突的问题
解决寄存器冲突的简捷方法是:
在子程序的开始将子程序中所有用到的寄存器中的内容都保存起来,在子程序返回前再恢复。
可以用栈来保存寄存器中的内容。