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

Я пытаюсь написать код ассемблера в mbr, чтобы использовать ISR BIOS. Я пишу следующий код в 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 на символы, и он хорошо печатается. Я использую процессор AMD PhenomII 955, я что-то сделал не так?


person social_loser    schedule 13.09.2016    source источник
comment
Инициализируйте регистры сегментов чем-то вроде xor ax, ax mov ss, ax mov ds, ax. Инструкция mov al, [...] использует ds, а push ... использует ss. Убедитесь, что они равны.   -  person Margaret Bloom    schedule 13.09.2016
comment
@MargaretBloom Это работает! Спасибо ! пожалуйста, опубликуйте его как ответ, тогда я могу отметить этот вопрос как ответ.   -  person social_loser    schedule 13.09.2016


Ответы (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.

person Margaret Bloom    schedule 13.09.2016
comment
Поскольку OP явно не отключает прерывания (теоретически BIOS может оставить их включенными до перехода в код загрузочного сектора), считаете ли вы, что разумно обновить SS без изменения SP тоже? Я бы, вероятно, просто четко указал, что при обновлении SS: SP вы обновляете SS, а затем SP сразу после (Обновите до SS и прерывания отключены до конца следующей инструкции) или просто используйте CLI, чтобы отключить их на время кода запуска. - person Michael Petch; 14.09.2016
comment
@MichaelPetch Вы абсолютно правы. Обновляю ответ. - person Margaret Bloom; 14.09.2016