【发布时间】:2011-01-19 03:32:59
【问题描述】:
首先我了解(或我认为我了解)未对齐堆栈的问题。
但我知道(就像定义一样)将 16 位值推入 32 位宽的堆栈可能会导致堆栈未对齐。
但我不明白的是,这是怎么发生的……因为PUSH 和POP 检查段描述符中的 D 标志(1 递增/递减 32 位和 0 16 位也是如此)。
假设 D 标志=1,PUSH AX 应该减少 32 位吗?所以它就像我“错过”堆栈中的 16 位?
我不确定我是否理解这个问题
【问题讨论】:
首先我了解(或我认为我了解)未对齐堆栈的问题。
但我知道(就像定义一样)将 16 位值推入 32 位宽的堆栈可能会导致堆栈未对齐。
但我不明白的是,这是怎么发生的……因为PUSH 和POP 检查段描述符中的 D 标志(1 递增/递减 32 位和 0 16 位也是如此)。
假设 D 标志=1,PUSH AX 应该减少 32 位吗?所以它就像我“错过”堆栈中的 16 位?
我不确定我是否理解这个问题
【问题讨论】:
虽然push 和pop 都检查段描述符中的D 位以确定默认操作数大小(即16 或32/64 位),但它可以被操作数大小覆盖0x66 覆盖。
如果 D 位为 0,则:
ff /6
将 16 位推入堆栈
和
66 ff /6
推送 32 位(如果是 64 位段,则推送 64 位)。
如果 D 位为 1,则相反。
在任何情况下,ESP(或 RSP 或只是 SP,取决于地址大小)递增或递减 2(对于 16 位操作)、4(对于 32 位操作)或 8(用于 64 位操作)。
【讨论】: