首先我了解(或者我认为我了解)堆栈未对齐的问题。
但我知道(就像定义一样)将 16 位值插入 32 位宽堆栈可能会导致堆栈未对齐。
但我不明白的是,这是如何发生的......因为 PUSH
和 POP
检查段描述符处的 D 标志(1 增量/减 32 位,为 0 16 位)。
假设 D flag=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 位操作)。
关于assembly - 汇编器堆栈对齐(或使用 PUSH 更好的未对齐示例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2302661/