Почему этот код в реальном режиме работает на виртуальной машине, но не работает на моей реальной машине?

Я пытаюсь написать код сборки в mbr, чтобы использовать BIOS ISR. Я пишу следующий код в mbr, ожидая, что символы "ABCD" будут напечатаны на экране:

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

этот код хорошо работает на симуляторе bochs или qemu, но когда я пишу на свой реальный диск и использую его для загрузки, ничего не печатается. Я проверил, чтобы непосредственно установить регистр%al в chars, и он хорошо печатается. Я использую процессор AMD PhenomII 955, я что-то не так сделал?

1 ответ

Решение

Инициализируйте регистры сегмента с чем-то вроде

xor ax, ax       ;Initialize seg regs with 0
mov ss, ax 
mov ds, ax 

Инструкция mov al, [...] использования ds в то время как push ... использования ss,
Убедитесь, что они равны.


Я не упомянул об этом, но, как справедливо заметил Майкл, вы должны быть осторожны при обновлении SS,
Пара SS:SP должно обновляться атомарно относительно прерываний, иначе прерывание, инициированное на полпути во время инициализации, будет использовать SS:SP пара не полностью действительна.

Самый простой способ сделать это - обновить sp сразу после инициализации ss

mov bp, 0x8000
mov ss, ax
mov sp, bp

поскольку процессор запрещает прерывания для всей инструкции после mov ss, ...,
В противном случае вы можете явно обернуть код инициализации в clisti пара.

Другие вопросы по тегам