在 x86 32 位保护模式下,使用 PUSH/POP 指令时,我们还可以使用 SP 而不是 ESP 寄存器吗?

Kai*_*ang 1 x86 assembly protected-mode

不知道什么时候用SP寄存器,什么时候用ESP寄存器,另外我想知道什么时候用ESP寄存器,是不是总是减4不能减2?

har*_*old 5

技术上SP可以用在pushpop在32位模式,但它需要修改一个标志,你通常不能更改。

在 pmode 中是使用 SP 还是 ESP 由 引用的段描述符中的 B 标志控制SS。通常在用户模式代码中,这不是您有权访问的内容,因此您无法更改它。

有(为默认操作数大小和默认地址尺寸类似但独立的机制不是,平原地址大小用于存储器操作数为堆栈地址大小同样的事情push [mem]pop [mem])。这是3个独立的东西,见下文。

使用ESP寄存器时,是否总是减4,不能减2

推/弹出 aword是可能的,甚至很容易,它仍然是 64 位模式。为此,您只需要操作数大小覆盖前缀 66h。例如push dx在 32 位甚至 64 位模式下都是绝对可编码的(尽管我不建议使用它)。这与是否使用 SP 或 ESP 无关。

所以有三种不同的尺寸在起作用,其中两个有一个覆盖前缀可以改变它:

  1. 操作数大小,压入 aworddword,这决定了堆栈指针移动 2 位还是 4 位。通常在 32 位模式下,默认大小将设置为 32 位,但操作数大小覆盖前缀可用于push dx在 32 位模式下进行编码(甚至在 64 位模式下)。
  2. 地址大小,这是pushpop用显式存储器操作数,而不是隐式的堆栈单元。例如,地址大小覆盖前缀可用于编码push dword [bx],两个前缀可一起用于编码push word [bx]。在 64 位模式下,地址大小覆盖前缀会导致地址被解释为 32 位地址,而不是 16 位地址,因此push qword [bx]是不可能的。
  3. 堆栈地址大小,仅由堆栈段描述符中的 B 标志决定,没有覆盖前缀。