我知道pushad将所有32位寄存器压入堆栈,但最终存储在堆栈中的唯一寄存器是EDI。标志值不受影响,那么使用pushad有什么意义呢?另外,我知道pushfd以双格式推送所有标志值。那么,如果标志值通常只有0或1,那么pushfd操作如何将诸如00000A46之类的值推送到堆栈?
答案 0 :(得分:27)
...最终存储在堆栈中的唯一寄存器是EDI。
没有。 PUSHAD指令始终将所有 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寄存器中的位的值。