【问题标题】:How ret works if pop cs:ip isn't allowed如果 pop cs:ip 不允许,ret 如何工作
【发布时间】:2013-12-22 09:36:55
【问题描述】:

我正在阅读装配艺术,第 250 页上写着:

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

第 291 页上写着:

retf: popd cs:ip

在我看来,有两种选择:
pop cs: ip 是允许的,但你不应该使用它,因为 ret 指令更短。
pop cs:ip 是不允许的,只有 ret 指令才能做到。

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

【问题讨论】:

  • “这是否意味着我们所做的每个 CALL 都是 FAR-JUMP?” IIRC,它们都是 NEAR 处于 32 位保护模式(因为它们都会位于您的单个 4GB“段”内)。
  • @Michael:错了;远跳转/调用指令仍然存在于 32 位保护模式中。一些操作系统(或 DOS 扩展程序)甚至使用分段的 32 位内存模型(其中指针长度为 48 位)。然而,大多数操作系统使用非分段内存布局。

标签: assembly x86


【解决方案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 决定的,所以它仍然是可能的。

【讨论】:

  • 所有这些指令都接近跳转指令。最初的问题是关于修改 CS 和 RIP 寄存器的段间跳转(“远跳转”)。
  • @MartinRosenau, Do we always push a 32 bit address or NEAR-JUMP still exists? 所以这不仅仅是关于跨部门的电话。
  • 嗯。我认为问题是问题本身。答案应该是32位的近跳和远跳是不一样的。
  • pop cs 曾经在 8086 上工作,但现在操作码 0x0F 被用作前缀字节。为数不多的已被删除的操作码之一。
  • 你可以在这里找到详细的答案:stackoverflow.com/questions/4039325/… 简短的回答是,段不是真正的段,而是选择器,它加起来不超过 6 字节的线性地址空间。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-27
    • 2018-11-06
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多