王爽汇编语言学习笔记(十) --CALL和RET指令

时间:2022-01-23 19:27:36


callret指令都是转移指令,他们都修改IP,或同时修改CSIP

2 ret retf

  ret 指令用栈中的数据修改IP的内容,从而实现近转移;

  retf 指令用栈中的数据,修改CSIP的内容,从而实现远转移;

CPU执行ret指令时,进行下面两部操作:IP =((ss)*16+(sp)) sp = sp+2 = pop IP

CPU执行retf指令时,进行1IP =((ss)*16+(sp)) 2sp = sp+2  3CS = 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 3IP =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 16reg  = 1) push IP   2) jmp 16reg

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.  callret的配合使用

利用callret来实现子程序的机制。

6. mul指令

   mul reg

   mul 内存单元

两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认放在AL中,另一个放在8reg或内存字节单元中;如果是16位,一个默认在AX中,另一个放在16reg或内存字单元中。

结果:如果是8位乘法,结果默认放在AX中;如果是16位乘法,结果高位默认存放在DX中,低位在AX中。

7. 参数传递问题

   比如设计一个子程序,可以根据提供的N,来计算N3次方。这里存在两个问题

1) 将参数N存储在什么地方?

2) 计算得到的数值,存储在什么地方?

  1.使用寄存器传递

  2.批量数据的传递:将批量数据存放到内存中,然后将他们所在的内存空间的首地址放在寄存器中,传递给需要的子程序。对于具有批量数据的返回结果,也可用同样的方法。

3) 使用栈传递