views:

96

answers:

4

Title says it all.

"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 to 0x3FF while my instruction pointer starts at 0x7C00? To me the most intuitive place for SP would be right below 0x7C00.

A: 

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?

Jens Björnhager
You usually don't have data in the code segment but in it's own memory space. That's why you get different segment pointers if you declare variables in a data segment. If you don't, then obviously DS needs to be set to CS.
Jens Björnhager
Perhaps you should ask why the *system* sets the registers that way. Perhaps they are that way because you have not set them otherwise?
Jens Björnhager
If it were obvious, why is this question here? My conjecture is that NASM doesn't set your SP at all.
Jens Björnhager
Thus it is obvious that my OP was laid out carelessly causing literal/meticulous people like you, Jens, to misinterpret what i'm after. I'm sorry for that.Maybe better luck next time.
Laurimann
A: 

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...

Laurimann
A: 

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.

Earlz
Thank you Earlz. Although you didn't answer the question at hand you provided good guidance on how to live with the realities we face.What's new to me in your example is the last jump. I'll prolly should add it to my own implementations aswell. Can you refer me to (online) resources where i could learn more about these BIOS bugs and necessary setup sequences from OS writer's perspective?
Laurimann
@Lau how did my answer not work for you? The stack will not be setup by the BIOS. You have to do it yourself. And the problem with the BIOS is that there is no formal standard. It's basically just an informal agreement between computer makers.
Earlz
@Lau if you're curious to the last line though, see http://stackoverflow.com/questions/2630899/hello-world-bootloader-not-working/2631434#2631434 for a detailed explanation.
Earlz
While your answer worked it obviously didn't address the "why?" of my problem - is est "what DOES SET the stack pointer to such odd value and more importantly WHY does it do so?". I have learned that it certainly is not NASM and that it most probably is BIOS. To confirm this i would need access to my BIOS' detailed specifications and/or source code - impossible!From one thing to another, thank you for the link about "the last line". It was very enlighting.
Laurimann
@Laur you should note that there is no "BIOS specification" it's more of a convention that PCs follow.. there is no standard..
Earlz
+2  A: 

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

Mike Gonta