Why is my boot loader's stack segment at 0x3FF (end of Real Mode IVT)?
"address 0x500 is the last one used by the BIOS" is what Wikipedia -
"00000000-000003FF Real Mode IVT (Interrupt Vector Table)" is what osdev.org's article over the BIOS memory map says.
So can you tell me why NASM places my .com file's stack pointer t开发者_C百科o 0x3FF while my instruction pointer starts at 0x7C00? To me the most intuitive place for SP would be right below 0x7C00.
The simple answer is that the boot sector has a valid (and probably small) stack which was used by the BIOS.
The happy answer is that 3FFh is a valid stack location for some BIOS. The fact that in this case it is the lower part of the IVT is because those interrupt vectors are not used by the BIOS. It is no secret.
BIOS Stack Area
The BIOS uses 30:0000h - 30:00FFh (on top of the interrupt vector table) as a stack area. This area is used for BIOS calculations and temporary storage. The addresses for INTs C0h through FFh, not supported in the AMIBIOS, would ordinarily occupy this space.Programmer's Guide to the AMIBIOS 1993, page 181
I don't believe BIOSes are expected to maintain a valid stack for you. So you should setup a stack yourself in whatever free memory you have. My general startup sequence in bootloaders is as so:
[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 Does not do anything than what you tell it. This is the point of using assembly. Every line of assembly code has a 1:1 ratio of opcodes executed by the computer. So, if the BIOS does not setup a stack for you, and no where in your assembly code do you setup a stack, then the stack will be in some invalid state. Nasm will not insert magic code to setup a stack.
I'm not familiar with NASM, but I'm pretty sure it sets your Stack Segment register (SS) to something else than 0, so SS:SP points somewhere entirely different.
Edit: Wait, is your segment or pointer set to 03FF?
It's not the assembler that alters the contents of register(s) (by any hidden commands in the executable file, in this case the bootleader).
According to Intel manual it's neither the CPU that causes SP to contain such odd value. http://www.intel.com/design/pentiumii/manuals/243192.htm
Because there's no existing OS in which the code is run the only option left to cause the state of SP (and other registers) is BIOS. Unfortunately BIOSes are closed source "trade secrets" and thus the question "why" will be left answered. Coreboot at http://www.coreboot.org/Welcome_to_coreboot might give some hints to why things are like they are but Coreboot seems to do things sometimes very different from traditional BIOSes...
精彩评论