如果不允许pop cs:ip,ret如何工作

时间:2013-12-05 12:31:29

标签: assembly x86

我正在阅读装配艺术,并在第250页上说:

  

你只能推送cs寄存器(弹出cs寄存器会产生一些有趣的程序流控制问题)。

在第291页上它说:

  

retf:popd cs:ip

我认为有两种选择:
pop cs:ip是允许的,但你不应该使用它,因为ret指令更短 pop cs:不允许使用ip,只有ret指令可以执行。

此外,如果过去使用call和ret使用分段,并且在现代计算机中这个“hack”不再使用(或仅由OS程序员使用),这是否意味着我们所做的每一个CALL都是FAR-JUMP ?
我们总是推送32位地址还是NEAR-JUMP仍然存在?

2 个答案:

答案 0 :(得分:1)

Intel Developer Manual Volume 2中,您可以看到近跳跃的操作码仍然存在。所以答案是,不,不是每次通话/跳转都需要远程通话。

一些例子:

EB cb JMP rel8 Jump short, RIP = RIP + 8-bit displacement sign extended to 64-bits
E9 cw JMP rel16 Jump near, relative, displacement relative to next instruction. Not supported in  64-bit mode.
E9 cd JMP rel32 Jump near, relative, RIP = RIP + 32-bit displacement sign extended to 64-bits
...
EA cd JMP ptr16:16 Jump far, absolute, address given in operand
EA cp JMP ptr16:32 Jump far, absolute, address given in operand
FF /5 JMP m16:16 Jump far, absolute indirect, address given in m16:16
FF /5 JMP m16:32 Jump far, absolute indirect, address given in m16:32.
REX.W + FF /5 JMP m16:64 Jump far, absolute indirect, address given in m16:64. Op

通常编译器/汇编器根据距离选择使用哪个操作码。当然,在汇编程序中,您可以通过特定请求一定距离来影响它(如果您想在运行时修补代码,则可能需要这些距离)。

关于分段切换,在Windows保护模式环境中已经删除了对此的需求,因为使用了平面内存模型。然而,这是操作系统的决定,而不是由CPU决定,因此它仍然是可能的。

答案 1 :(得分:1)

“跳远绝对”指令仍然存在于32位模式;它长7个字节(0xEA,4个字节偏移,2个字节段)。

某些操作系统甚至使用了分段的32位内存布局,其中指针的大小为48位。

然而,这是相当低效的,因为32位地址分割不会带来任何好处,但由于分段处理,只会使程序变得越来越慢。因此,大多数操作系统不再使用分段(中断处理程序和系统调用条目除外)。