在x86实模式中选择堆栈指针地址(对齐)

时间:2017-01-25 20:38:46

标签: x86 bootloader real-mode

我已经明白,应该将堆栈指针与2字节边界对齐。换句话说,不应该将SP设置为以0xF(或任何其他奇数)结尾的值。

如果我使用0xFFFF作为SP,会发生什么?所有64kB都可用,还是少一个字节?

如果我想要一个1024字节的堆栈大小,我应该将SP设置为0x3FF还是0x400?例如是SS(堆栈段)指向要使用的字节?

他们声明here一个人也不应该使用以0xE结尾的SP地址,“浪费字节在0x..E和0x..F ”。怎么样?

1 个答案:

答案 0 :(得分:1)

x86堆栈完全降序 完整表示堆栈指针指向最后推送的项目。这与空降序/升序堆栈形成对比,其中堆栈指针指向下一个空闲位置。

基本上,这归结为push ax

的语义
sub sp, 02h
mov WORD [sp], ax 

当您将堆栈指针sp设置为地址 X 时, X 被视为最后一个项目的位置,因此不会被使用。
如果将sp设置为0xe,则推送将sp移动到0xe - 2 = 0xc并在其中写入其操作数。不触及0xe及以上的存储器。

使用sp的奇数地址会对性能产生负面影响,因为未对齐的内存访问的延迟可能是对齐访问的延迟的两倍。
对于小于DRAM总线宽度的数量(在写入时为8字节),这种惩罚会有所降低 考虑堆栈的使用频率,值得保持对齐。

sp的奇数地址开始将导致堆栈指针达到1时出现问题。 推送会将sp设置为0xffff,但随后写入一个字将触发#SS,因为较高的字节超出ss限制。
反过来,使用混乱的堆栈引发异常将引发另一个CPU将作为#DF发送的#SS。 但堆栈仍然混乱,因此产生第三个异常,三重故障,CPU将重置 因此,堆栈指针不对齐没有任何好处。

如果你想要大小 S 的堆栈,你将sp设置为 S mod 2 16 授予2< = S < = 64KiB 您可以通过写下 S 的小值(例如4)来检查这是否正确。
您还可以检查设置sp为0将为您提供64KiB堆栈,这是实际模式中自然可用的最大尺寸。