1 call和ret指令都是转移指令,他们都修改IP,或同时修改CS和IP。
2 ret retf
ret 指令用栈中的数据修改IP的内容,从而实现近转移;
retf 指令用栈中的数据,修改CS和IP的内容,从而实现远转移;
CPU执行ret指令时,进行下面两部操作:IP =((ss)*16+(sp)) sp = sp+2 = pop IP
CPU执行retf指令时,进行1)IP =((ss)*16+(sp)) 2)sp = sp+2 3)CS = SS*16+SP 4) SP=SP+2
= 1) POP IP 2) POP CS
3 CALL指令
Call指令不能实现短转移,除此之外,call指令实现转移的方法和jmp指令的原理相同
1. 依据位移来进行转移的call指令
call 标号(将当前的IP压栈后,转到标号处执行指令)
1) sp = sp -2 2) IP = SS*16+SP 3)IP =IP +16位移
16位位移 = 标号处的地址 - call指令后的第一个字节的地址;
16位位移的范围 -32768~323767,用补码表示;
16位位移由编译程序在编译时算出。
Call 标号 = push IP jmp near ptr 标号
2. 转移的目的地址在指令中的call指令
Call far ptr 标号 实现的是段间转移。
1) sp =sp -2 2)ip = ss*16+sp 3) sp=sp-2 4) ip = ss*16+sp
CS = 标号所在的段地址 IP = 标号在段中的偏移地址
Push CS push IP jmp near far 标号
3. 转移地址在寄存器中的call指令
Call 16位reg = 1) push IP 2) jmp 16位reg
4. 转移地址在内存中的call指令
1) call word ptr 内存单元地址
1)Push ip 2) jmp word ptr 内存单元地址
2) call dword ptr 内存单元地址
1)push CS push IP 2) jmp dword ptr 内存单元地址
5. call和ret的配合使用
利用call和ret来实现子程序的机制。
6. mul指令
mul reg
mul 内存单元
两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认放在AL中,另一个放在8位reg或内存字节单元中;如果是16位,一个默认在AX中,另一个放在16位reg或内存字单元中。
结果:如果是8位乘法,结果默认放在AX中;如果是16位乘法,结果高位默认存放在DX中,低位在AX中。
7. 参数传递问题
比如设计一个子程序,可以根据提供的N,来计算N的3次方。这里存在两个问题
1) 将参数N存储在什么地方?
2) 计算得到的数值,存储在什么地方?
1.使用寄存器传递
2.批量数据的传递:将批量数据存放到内存中,然后将他们所在的内存空间的首地址放在寄存器中,传递给需要的子程序。对于具有批量数据的返回结果,也可用同样的方法。
3) 使用栈传递