要回答这个问题,请考虑call指令的作用。
如果您不确定,请查看:
在实地址或虚拟 8086 模式下执行远调用时,处理器将 CS 和 EIP 寄存器的当前值压入堆栈,用作返回指令指针。然后,处理器执行到代码段的“远分支”和被调用过程的目标操作数指定的偏移量。
此处目标操作数直接使用指针(ptr16:16 或 ptr16:32)或间接使用内存位置(m16:16 或 m16:32)指定绝对远地址。使用指针方法,被调用过程的段和偏移量在指令中编码,使用 4 字节(16 位操作数大小)或 6 字节(32 位操作数大小)远地址立即数。使用间接方法,目标操作数指定包含 4 字节(16 位操作数大小)或 6 字节(32 位操作数大小)远地址的内存位置。操作数大小属性确定远地址中偏移量(16 位或 32 位)的大小。远地址直接加载到 CS 和 EIP 寄存器中。如果操作数大小属性为 16,则清除 EIP 寄存器的高两个字节。
你被告知IP(指令指针)是300H,CS(代码段)是1075H。文档说会发生什么?
首先,CS以及IP将从调用返回时被压入堆栈以备后用。
然后,处理器分支到指定的代码段和偏移量。
在这种情况下,这将是1000H。
这将如何影响CS和IP?嗯,CS会一样,因为你没有改变段,但IP会改变。为什么IP会变?想想什么IP 是:它是一个指向即将执行的指令的指针。如果执行跳转到1000H,那么将要执行的指令显然在1000H,IP也将是1000H。
你ret离开后会发生什么call?旧的CS和IP(被推入堆栈的call)被弹出。CS仍然不会改变,但IP现在会300H再次改变!
(注意这不会造成死循环。为什么?因为工作方式IP。在指令解码时内部设置为指向下一条要执行的call指令。因此,当指令正在执行时,IP指向该指令after call。因此,当您 return 和 pop 时IP,您将在.)之后开始执行call。