简体   繁体   中英

why these real-mode code works in virtual machine but not working on my real machine?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM