16位直接绝对远调用

16位直接绝对远调用

Content #

这种调用属于段间调用,即调用另一个代码段内的过程,所以称为远调用(far call)。很容易想到,远调用既需要被调用过程所在的段地址,也需要该过程在段内的偏移地址。

“16 位”是针对偏移地址来说的,而不是限定段地址,尽管段地址事实上也是 16 位的;“直接”的意思是,段地址和偏移地址直接在call 指令中给出了。当然,这里的地址也是绝对地址。比如:

call 0x2000:0x0030

这条指令编译后的机器码为9A 30 00 00 20,0x9A 是操作码,后面跟着的两个字分别是偏移地址和段地址,按规定,偏移地址在前,段地址在后。

处理器执行过程如下:

  1. 将代码段寄存器CS 的当前内容压栈,
  2. 再把指令指针寄存器IP 的当前内容压栈。
  3. 用指令中给出的段地址代替CS 原有的内容,
  4. 用指令中给出的偏移地址代替IP 原有的内容。这直接导致处理器从新的位置开始执行。

处理器是没有脑子的。如果被调用过程位于当前代码段内,而你又用这种指令格式来调用它,那么,处理器也会不折不扣地从当前代码段“转移”到当前代码段。

From #