为什么我的引导加载程序的堆栈段位于0x3FF(实模式IVT结束)?

时间:2010-04-29 14:15:54

标签: assembly x86 stack bios bootloader

“地址0x500是BIOS使用的最后一个”是Wikipedia      -

“00000000-000003FF实模式IVT(中断向量表)”是osdev.org关于BIOS内存映射的文章所说的。

那么你能告诉我为什么NA​​SM将我的.com文件的堆栈指针放到0x3FF而我的指令指针从0x7C00开始?对我来说,SP最直观的地方就是0x7C00。

4 个答案:

答案 0 :(得分:3)

简单的答案是引导扇区具有BIOS使用的有效(可能很小)堆栈。

  

很高兴的答案是3FFh是某些BIOS的有效堆栈位置。在这种情况下它是IVT的下半部分的事实是因为BIOS不使用那些中断向量。这不是什么秘密。

  

BIOS堆栈区域
  BIOS使用30:0000h-30:00FFh(在中断向量表的顶部)作为堆栈区域。该区域用于BIOS计算和临时存储。在AMIBIOS中不支持的INTs C0h到FFh的地址通常会占用这个空间。

     

1993年AMIBIOS程序员指南,第181页

答案 1 :(得分: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 不会插入魔术代码来设置堆栈。

答案 2 :(得分:0)

我不熟悉NASM,但我很确定它会将你的堆栈段寄存器(SS)设置为0以外的其他值,所以SS:SP指向完全不同的地方。

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

答案 3 :(得分:0)

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

根据英特尔手册,它既不是导致SP包含这种奇数值的CPU。 http://www.intel.com/design/pentiumii/manuals/243192.htm

因为没有运行代码的现有操作系统,导致SP(和其他寄存器)状态的唯一选择是BIOS。不幸的是,BIOS是封闭源“商业秘密”,因此将回答“为什么”这个问题。 http://www.coreboot.org/Welcome_to_coreboot的Coreboot可能会给出一些提示,说明为什么事情就像它们一样,但Coreboot似乎做的事情有时与传统的BIOS有很大不同......