Почему этот код в реальном режиме работает на виртуальной машине, но не работает на моей реальной машине?
Я пытаюсь написать код сборки в 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, ...
,
В противном случае вы можете явно обернуть код инициализации в cli
sti
пара.