“地址 0x500 是 BIOS 使用的最后一个地址”是Wikipedia -
“00000000-000003FF 实模式 IVT(中断向量表)”是osdev.org关于 BIOS 内存映射的文章所说的。
那么你能告诉我为什么 NASM 将我的 .com 文件的堆栈指针放在 0x3FF 而我的指令指针从 0x7C00 开始吗?对我来说,SP 最直观的位置就在 0x7C00 下方。
简单的答案是引导扇区有一个有效的(并且可能很小)堆栈,它被 BIOS 使用。
满意的答案是 3FFh 是某些 BIOS 的有效堆栈位置。在这种情况下,它是 IVT 的较低部分,这是因为 BIOS 不使用这些中断向量。这不是什么秘密。
BIOS 堆栈区
BIOS 使用 30:0000h - 30:00FFh(在中断向量表的顶部)作为堆栈区。该区域用于 BIOS 计算和临时存储。在 AMIBIOS 中不支持的 INT C0h 到 FFh 的地址通常会占用这个空间。AMIBIOS 1993 程序员指南,第 181 页
我不相信 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不会插入魔术代码来设置堆栈。
改变寄存器内容的不是汇编程序(通过可执行文件中的任何隐藏命令,在这种情况下是引导程序)。
根据英特尔手册,导致 SP 包含这种奇数值的既不是 CPU。 http://www.intel.com/design/pentiumii/manuals/243192.htm
因为没有运行代码的现有操作系统,所以导致 SP(和其他寄存器)状态的唯一选项是 BIOS。不幸的是,BIOS 是封闭源代码的“商业机密”,因此“为什么”的问题将得到解答。http://www.coreboot.org/Welcome_to_coreboot上的 Coreboot可能会给出一些提示,说明为什么事情会像现在这样,但 Coreboot 似乎做的事情有时与传统的 BIOS 非常不同......
我不熟悉 NASM,但我很确定它会将您的堆栈段寄存器 (SS) 设置为 0 以外的值,因此 SS:SP 指向完全不同的地方。
编辑:等等,你的段或指针是否设置为 03FF?