我的启动加载程序为什么堆栈段位于0x3FF(实模式IVT末尾)?

3
“address 0x500是BIOS最后使用的地址”是维基百科上的内容。
“00000000-000003FF实模式IVT(中断向量表)”是osdev.org的文章中关于BIOS内存映射的说法。
那么你能告诉我为什么NASM将我的.com文件的堆栈指针放置在0x3FF,而指令指针从0x7C00开始吗?对我来说,SP最直观的位置应该在0x7C00下面。
4个回答

3
简单的回答是,引导扇区有一个有效(可能很小)的堆栈,被BIOS使用。
愉快的答案是,对于某些BIOS来说,3FFh是一个有效的堆栈位置。在这种情况下,它是IVT的较低部分,因为这些中断向量不被BIOS使用。这并不是秘密。
BIOS堆栈区域 BIOS使用30:0000h - 30:00FFh(在中断向量表的顶部)作为堆栈区域。该区域用于BIOS计算和临时存储。 INTs C0h到FFh的地址,在AMIBIOS中不受支持,通常会占据这个空间。
《AMIBIOS程序员指南1993年版》,第181页

1

我不认为BIOS应该为您维护有效的堆栈。因此,您应该在任何可用的空闲内存中自己设置堆栈。我的引导加载程序中一般的启动序列如下:

[BITS 16]
[ORG 0x7C00]
xor ax,ax ;AX=0
mov ds,ax
mov es,ax ;can be omitted
mov ss,ax
mov sp,0x7000 ;or replace with some other nice valid piece of memory
jmp word 0:begin ;BIOSes are sometimes buggy and load you initially with CS=7C0
begin:
;....

NASM不会做除你告诉它的事情以外的任何事情。这就是使用汇编的重点。每一行汇编代码都有一个1:1的比率,由计算机执行操作码。因此,如果BIOS没有为您设置堆栈,并且在您的汇编代码中没有设置堆栈,则堆栈将处于某种无效状态。NASM不会插入魔术代码来设置堆栈。


谢谢你,Earlz。虽然你没有回答问题,但是你提供了如何应对我们面临的现实的好指导。在你的例子中,对我来说新的是最后一跳。我可能也应该将其添加到我的实现中。你能否向我推荐(在线)资源,让我可以从操作系统编写者的角度了解更多关于这些BIOS漏洞和必要的设置序列的知识? - Laurimann
@Lau,我的答案为什么对你没用?BIOS不会设置堆栈,你必须自己设置。而且BIOS的问题在于没有正式的标准,它基本上只是计算机制造商之间的非正式协议。 - Earlz
@Lau 如果你对最后一行感到好奇,可以访问https://dev59.com/Vk3Sa4cB1Zd3GeqPsyck#2631434 查看详细的解释。 - Earlz
虽然你的回答解决了我的问题,但很明显没有解释问题的“为什么”——那就是“究竟是什么将堆栈指针设置为这样奇怪的值,更重要的是为什么会这样做?”我已经了解到它肯定不是NASM,很可能是BIOS。要确认这一点,我需要访问我的BIOS详细规格和/或源代码——但这是不可能的!顺便说一句,感谢你提供的“最后一行”的链接,非常有启发性。 - Laurimann
@Laur 你应该注意到,没有所谓的“BIOS规范”,这更像是PC遵循的一种惯例.. 没有标准.. - Earlz

0

我不熟悉NASM,但我相当确定它会将您的堆栈段寄存器(SS)设置为与0不同的值,因此SS:SP指向完全不同的位置。

编辑:等等,您的指针是否设置为03FF?


通常情况下,代码段中没有数据,而是有它自己的内存空间。这就是为什么如果在数据段中声明变量,您会得到不同的段指针。如果不这样做,那么显然需要将DS设置为CS。 - Jens Björnhager
也许你应该问为什么系统会这样设置寄存器。也许它们之所以那样是因为你没有另外设置它们? - Jens Björnhager
如果这是显而易见的,那么为什么还会有这个问题呢?我的猜测是NASM根本没有设置你的SP。 - Jens Björnhager
因此很明显我的 OP 布局不够仔细,导致像你 Jens 这样的字面/一丝不苟的人误解了我的意思。对此我感到抱歉。也许下次会更好运。 - Laurimann

0

汇编语言并不会通过可执行文件中的任何隐藏命令来改变寄存器的内容(在这种情况下是引导程序)。

根据英特尔手册,CPU 也不会导致 SP 包含如此奇怪的值。 http://www.intel.com/design/pentiumii/manuals/243192.htm

因为没有现有的操作系统可以运行代码,所以导致 SP(和其他寄存器)状态的唯一选择是 BIOS。不幸的是,BIOS 是闭源的“商业机密”,因此“为什么”这个问题将无法得到回答。Coreboot 在 http://www.coreboot.org/Welcome_to_coreboot 可能会给出一些关于为什么事情是这样的提示,但 Coreboot 有时似乎与传统 BIOS 做事情非常不同...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接