The bootstrap sequence in the BIOS will load the first valid MBR that it finds into the computer's physical memory at address 0x7C00.
Which value should be used for SP for booting process?
org 7c00h ; set location counter.
mov ax, XXX ; What is XXX?
mov sp, ax
; Now PUSH an POP are safe
Any value of SS:SP
such that there's enough stack space for your code AND interrupt service routines is OK.
And, of course, your stack shouldn't collide with any of your code or other data or run into ROM or a memory-mapped device address range.
The BIOS does not guarantee what SS:SP
your boot sector will receive. So, changing only SP
isn't right.
You could for example do this (if there isn't any code or data of yours at this location):
...
mov ax, 0
mov ss, ax
mov sp, ax
...
This will set SS:SP
to 0:0. Don't panic yet. The next push will first decrement SP
from 0 to 0xFFFE and write to 0:0xFFFE, not to 0:0.
This will give you 0x10000 - (0x7c00 + 0x200) = 33280 bytes of space between the end of your boot sector and the maximum stack pointer address. That's plenty of stack space.
Also note that when changing both SS
and SP
, you either have to do that with interrupts disabled or first change SS
and then change SP
in the immediately following instruction (like shown above).
Alternatively you could use the LSS SP, ...
instruction, but it takes as an argument an address of a far address, meaning your new SS:SP
value would first need to be somewhere in the memory.
Yet another way to change SS
and SP
is to use PUSH
and RETF
.
0000:0500 to 0007:FFFF is guaranteed free for use. Proper initialization looks like this:
org 0x0600
...
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
; relocate itself
mov si, sp
mov di, 0x0600
mov cx, 256
rep movsw
; make sure we'are at 0000:0600+x
jmp 0:.reloc
.reloc:
push 2
popf ; flags with all off
I use 7C00, stack goes downward and code goes upward. You may replace 7C00 with any valid range as mentioned, just make sure not overwrite your own code/data.
Btw, most MBR would relocate itself to 0000:0600 by tradition, and chain-load VBR into 7C00.
Also note the jmp .reloc, some buggy BIOS start MBR with 07C0:0000, so a jmp there make sure CS=0