call 和 ret 指令

call 和 ret 指令都是转移指令,它们都修改 IP,或同时修改 CS 和 IP。它们经常被用来实现子程序的设计。

 

10.1 ret 和 retf

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

  retf 指令用栈中的数据,修改 CS 和 IP 的内容,从而实现近远转移。

  CPU 执行 ret 指令时,进行下面两步操作:

  (1)(IP) = ((ss)*16 + (sp))

  (2)(sp) = (sp) + 2

  CPU 执行 retf 指令时,进行下面 4 步操作:

  (1)(IP) = ((ss)*16 + (sp))

  (2)(sp) = (sp) + 2

  (3)(CS) = ((ss)*16 + (sp))

  (4)(sp) = (sp) + 2

  可以看出,如果我们用汇编语法来解释 ret 和 retf 指令,则:

  CPU 执行 ret 指令时,相当于进行:

  pop IP

  CPU 执行 retf 指令时,相当于进行:

  pop IP

  pop CS

 

10.2 call 指令

  CPU 执行 call 指令时,进行两步操作:

  (1)将当前的 IP 或 CS 和 IP 压入栈中;

  (2)转移。

  call 指令不能实现短转移,除此之外,call 指令实现转移的方法和 jmp 指令的原理相同。

 

10.3 依据位移进行转移的 call 指令

  call 标号(将当前的 IP 压栈后,转到标号处执行指令)

  CPU 执行此种格式的 call 指令时,进行如下操作:

  (1)(sp) = (sp) - 2

      ((ss)*16+(sp)) = (IP)

  (2)(IP) = (IP) + 16位位移

  16位位移=标号处的地址 - call 指令后的第一个字节的地址;

  16位位移的范围为-32768~32767,用补码表示;

  16位位移由编译程序在编译时算出。

  从上面的描述中,可以看出,如果我们用汇编语法来解释此种格式的 call 指令,则:

  push IP

  jmp near ptr 标号

 

10.4 转移的目的地址在指令中的 call 指令

  前面讲的 call 指令,其对应的机器指令中并没有转移的目的地址,而是相对于当前 IP 的转移位移。

  call far ptr 标号,实现的是段间转移。

  CPU 执行此种格式的 call 指令时,进行如下操作:

  (1)(sp) = (sp) - 2

     ((ss)*16 + (sp)) = (IP)

     (sp) = (sp) - 2

    ((ss)*16 + (sp)) = (IP)

  (2)(CS) = 标号所在的段的段地址

    (IP)=标号在段中的偏移地址

  用汇编语法描述如下:

  push CS

  push IP

  jmp far ptr 标号

 

10.5 转移地址在寄存器中的 call 指令

  指令格式: call 16位reg

  功能:

  (sp) = (sp) - 2

  ((ss)*16 + (sp)) = (IP)

  (IP) = (16位reg)

  用汇编语法描述如下:

  push IP

  jmp 16位reg

 

10.6 转移地址在内存中的 call 指令

  转移地址在内存中的 call 指令有两种格式。

  (1) call word ptr 内存单元地址

  用汇编语法解释如下:

  push IP

  jmp word ptr 内存单元地址

  (2)call dword ptr 内存单元地址

  CPU 执行“call dword ptr 内存单元地址”时,相当于进行:

  push CS

  push IP

  jmp dword ptr 内存单元地址

  

  按书上的说法,其实(1)中的IP就是内存单元地址,(2)类似。

 

10.7 call 和 ret 的配合使用

  我们可以写一个具有一定功能的程序段,我们称其为 子程序,在需要的时候,用 call 指令转去执行。执行完之后,使用 ret 指令,从而转到 call 指令后面的代码处继续执行。

 

10.8 mul 指令

  mul 是乘法指令,我们用 mul 做乘法的时候,要注意以下两点:

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

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

 

posted @ 2017-11-01 22:14  佚名000  阅读(443)  评论(0)    收藏  举报