Content #
这种调用属于段间调用,即调用另一个代码段内的过程,所以称为远调用(far call)。很容易想到,远调用既需要被调用过程所在的段地址,也需要该过程在段内的偏移地址。
“16 位”是针对偏移地址来说的,而不是限定段地址,尽管段地址事实上也是 16 位的;“直接”的意思是,段地址和偏移地址直接在call 指令中给出了。当然,这里的地址也是绝对地址。比如:
call 0x2000:0x0030
这条指令编译后的机器码为9A 30 00 00 20,0x9A 是操作码,后面跟着的两个字分别是偏移地址和段地址,按规定,偏移地址在前,段地址在后。
处理器执行过程如下:
- 将代码段寄存器CS 的当前内容压栈,
- 再把指令指针寄存器IP 的当前内容压栈。
- 用指令中给出的段地址代替CS 原有的内容,
- 用指令中给出的偏移地址代替IP 原有的内容。这直接导致处理器从新的位置开始执行。
处理器是没有脑子的。如果被调用过程位于当前代码段内,而你又用这种指令格式来调用它,那么,处理器也会不折不扣地从当前代码段“转移”到当前代码段。