【问题标题】:Pushfd and Pushad: What's the point? [closed]Pushfd 和 Pushad:有什么意义? [关闭]
【发布时间】:2012-03-07 23:00:08
【问题描述】:

我知道 pushad 将所有 32 位寄存器推入堆栈,但最终存储在堆栈中的唯一寄存器是 EDI。标志值不受影响,那么使用 pushad 有什么意义呢?此外,我知道 pushfd 以双精度格式推送所有标志值。那么,如果 flag 值通常只有 0 或 1,pushfd 操作如何将 00000A46 等值压入堆栈?

【问题讨论】:

  • “最终存储在堆栈中的唯一寄存器是 EDI” - 您是如何得出这个结论的?
  • 不知道你从哪里得到的。您在 16 位代码中使用 pusha 和 pushf,在 32 位代码中使用 pushad 和 pushfd。 A46 有 12 位。
  • 这个问题毫无意义。 EDI位不正确,请解释一下。标志不受什么影响?什么是“双重格式”?您是在谈论标志还是 EFLAGS 寄存器?另外,我们是 32 位还是 16 位代码?等等。
  • EDI 是加载到堆栈中的最后一个寄存器,如果您在 x86 汇编中使用过它,它是唯一存储在堆栈中的值。
  • @user1210446 你的误解来自于pusha在每次写入堆栈之间递减esp,因此所有压入的寄存器最终都位于不同的地址。

标签: assembly x86 32bit-64bit


【解决方案1】:

...最终存储在堆栈中的唯一寄存器是 EDI。

没有。 PUSHAD 指令alwaysall 8 个通用寄存器压入堆栈。一条 PUSHAD 指令相当于写:

Push EAX
Push ECX
Push EDX
Push EBX
Push ESP
Push EBP
Push ESI
Push EDI

POPAD 以相反的顺序将值从堆栈中弹出,从而恢复所有寄存器值。

PUSHAD 和 POPAD 对于执行通用寄存器的简单保存和恢复很有用,而无需依次 PUSH 和 POP 每个单独的寄存器。

同样,PUSHFD 和 POPFD 用于保存和恢复 EFLAGS 寄存器。虽然在普通程序中并没有真正使用太多,但这些指令在(例如)执行进程上下文切换时(或必须恢复标志寄存器值的任何其他地方)很有用。

pushfd 操作如何将 00000A46 等值压入堆栈?

这就是解释数据的方式。 EFLAGS 寄存器是一组 32 位。如果将位分成 8 组,每组 4 (8*4=32),则可以将每个 4 位块映射到十六进制字符 (0..9,A-F)。同样,您可以将十六进制值转换回一组位:

00000A46 = 0000(0) 0000(0) 0000(0) 0000(0) 0000(0) 1010(A) 0100(4) 0110(6)

这些是存储在 EFLAGS 寄存器中的位的值。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
相关资源
最近更新 更多