I'm trying to write assemble code into mbr to use BIOS ISRs. I write the following code to the mbr, expecting the chars "ABCD" to be printed on the screen:
mov ah,0x0e
mov bp,0x8000
mov sp,bp
push 'A'
push 'B'
push 'C'
push 'D'
mov al, [0x7ffe]
int 0x10
mov al, [0x7ffc]
int 0x10
mov al, [0x7ffa]
int 0x10
mov al, [0x7ff8]
int 0x10
; infinite loop
jmp $
; padding 0s and set the magic number to make it bootable
times 510 -( $ - $$ ) db 0
dw 0xaa55
these code works well on the bochs or qemu simulator, but when I write to my real disk and use it to boot, nothing is printed. I've tested to directly set the %al register to chars , and it print well. I'm using a AMD PhenomII 955 processor, anything I 've done wrong ?
Initialize the segment registers with something like
xor ax, ax ;Initialize seg regs with 0
mov ss, ax
mov ds, ax
The instruction mov al, [...]
uses ds
while push ...
uses ss
.
Make sure they are equal.
I didn't mention it, but as Michael rightfully noted, you have to be careful when updating SS
.
The pair SS:SP
must be updated atomically with respect to interrupts, otherwise an interrupt triggered midway through the initialization will use a SS:SP
pair not fully valid.
The easiest way to do it is by updating sp
just after the initialization of ss
mov bp, 0x8000
mov ss, ax
mov sp, bp
beacuse the CPU inhibits the interrupts for the whole instruction after mov ss, ...
.
Otherwise you can explicitly wrap the initialization code in a cli
sti
pair.