i386/x64 pop FS/GS 指令支持一种变体,它将 SP 递增 32 位或 64 位而不是 16 位。这有什么用途?
An i386/x64 pop FS/GS instruction supports a variant where it increments the SP by 32 bits or 64 bits in stead of 16 bits. What is it used for?
根据 Intel® 64 和 IA-32 架构软件开发人员手册第 2 卷,pop fs
支持 3 种变体(pop gs
也是如此):
- 将栈顶弹出到FS;将堆栈指针递增 16 位。
- 将栈顶弹出到FS;将堆栈指针递增 32 位。 (在 compat/leg 模式下可用)
- 将栈顶弹出到FS;将堆栈指针递增 64 位。 (在 64 位模式下可用)
AMD64 文档操作 pop
没有明确描述堆栈指针发生了什么。我尝试制作这些,但似乎 gas 确实识别了它们(我假设它们需要 66h 前缀):
80490d6: 0f a1 pop fs
80490d8: 66 0f a1 popw fs
80490db: 0f a9 pop gs
80490dd: 66 0f a9 popw gs
我正在为这些而伤脑筋。据我了解,FS 和 GS 寄存器是 16 位,我知道它们有一个隐藏部分,但我不希望 pop
指令能够操纵它们,对吗?有人可以解释一下这些变体的目的是什么吗?
在32位模式下,每个栈槽都是32位的。如果在压入段寄存器后必须将堆栈指针调整为 4 字节的倍数,那将是相当烦人的,因此 CPU 提供了将段寄存器压入 4 字节堆栈槽的指令。
当段寄存器被压入操作数大小为 32 位时,寄存器内容被零扩展为双字。弹出时,只有低两个字节被读入段寄存器。高两个字节再次被忽略。
根据 Intel® 64 和 IA-32 架构软件开发人员手册第 2 卷,pop fs
支持 3 种变体(pop gs
也是如此):
- 将栈顶弹出到FS;将堆栈指针递增 16 位。
- 将栈顶弹出到FS;将堆栈指针递增 32 位。 (在 compat/leg 模式下可用)
- 将栈顶弹出到FS;将堆栈指针递增 64 位。 (在 64 位模式下可用)
AMD64 文档操作 pop
没有明确描述堆栈指针发生了什么。我尝试制作这些,但似乎 gas 确实识别了它们(我假设它们需要 66h 前缀):
80490d6: 0f a1 pop fs
80490d8: 66 0f a1 popw fs
80490db: 0f a9 pop gs
80490dd: 66 0f a9 popw gs
我正在为这些而伤脑筋。据我了解,FS 和 GS 寄存器是 16 位,我知道它们有一个隐藏部分,但我不希望 pop
指令能够操纵它们,对吗?有人可以解释一下这些变体的目的是什么吗?
在32位模式下,每个栈槽都是32位的。如果在压入段寄存器后必须将堆栈指针调整为 4 字节的倍数,那将是相当烦人的,因此 CPU 提供了将段寄存器压入 4 字节堆栈槽的指令。
当段寄存器被压入操作数大小为 32 位时,寄存器内容被零扩展为双字。弹出时,只有低两个字节被读入段寄存器。高两个字节再次被忽略。