2010-04-13 3 views
5

Я работаю над учебниками on this webpage, которые постепенно создают загрузчик, который отображает Hello World.Hello World bootloader не работает

2-й учебник (где мы пытаемся получить «A» для вывода) отлично работает, и все же первый учебник не работает для меня вообще! (BIOS полностью игнорирует дискету и загружается прямо в Windows). Это не проблема, хотя любые объяснения будут оценены.

Настоящая проблема заключается в том, что я не могу заставить 3-й учебник работать. Вместо этого при выводе «Hello World» я получаю необычный символ (и мигающий курсор) в нижнем левом углу экрана. Он выглядит немного как смайлик в круглом прямоугольнике. Кто-нибудь знает, как заставить Hello World отображать как следует?

ответ

7

Вы говорите «загрузитесь прямо в окна», поэтому я предполагаю, что вы используете физический ПК. В будущем обратите внимание: всегда используйте эмулятор для разработки! Это просто проще. Мне нравится Bochs для OSDeving, потому что у него хорошие функции отладки. Теперь, на возможное решение.

Существует много ошибок в BIOS, которые нарушают неофициальные спецификации IBM PC для адреса загрузки 0x7C00.

Это может вызвать множество проблем с адресами памяти и при каждом сборе. Так что начало выглядеть следующим образом:

[BITS 16] ;tell the assembler that its a 16 bit code 
[ORG 0x7C00] ;this tells the assembler where the code will be loaded at when it runs on your machine. It uses this to compute the absolute addresses of labels and such. 

jmp word 0:flush ;#FAR jump so that you set CS to 0. (the first argument is what segment to jump to. The argument(after the `:`) is what offset to jump to) 
;# Without the far jmp, CS could be `0x7C0` or something similar, which will means that where the assembler thinks the code is loaded and where your computer loaded the code is different. Which in turn messes up the absolute addresses of labels. 
flush: ;#We go to here, but we do it ABSOLUTE. So with this, we can reset the segment and offset of where our code is loaded. 
mov BP,0 ;#use BP as a temp register 
mov DS,BP ;#can not assign segment registers a literal number. You have to assign to a register first. 
mov ES,BP ;#do the same here too 
;#without setting DS and ES, they could have been loaded with the old 0x7C0, which would mess up absolute address calculations for data. 

Зе, часть нагрузки на 0x07C0:0000 и большую нагрузку (и его считать правильным в) в 0x0000:7C00. Это тот же плоский адрес, но различные настройки сегмента могут действительно испортить абсолютные адреса памяти. Так что давайте удалить «магию» ассемблер и посмотреть, как он выглядит (обратите внимание, я не гарантирую, адрес, чтобы быть совершенно правильно с этим. Я не знаю, размера всех опкодов)

jmp word 0:0x7C04 ;# 0x7C04 is the address of the `flush` label 
... 

Так , мы переходим к абсолютному адресу.

Теперь то.Что происходит, когда мы этого не делаем?

принять эту программу, например:

mov ax,[mydata] 
hlt 

mydata: dw 500 ;#just some data 

Это демонтирует к чему-то вроде

mov ax,[0x7C06] 

О, хорошо использует абсолютную адресацию, так как это могло пойти не так? Ну, а что, если DS на самом деле 0x7C0? то вместо получения ожидаемого ассемблера 0:0x7C06 он получит 0x7C0:0x7C06, которые не тот же плоский адрес.

Надеюсь, это поможет вам понять. Это действительно сложная тема, хотя и требуется некоторое время программирования низкого уровня, чтобы полностью понять.

+0

Привет, спасибо за ответ. К сожалению, ваш код не является синтаксически правильным в NASM. Это говорит мне о несоответствии размера операнда (??) в начале строки «jmp FAR 0x0000 ...». Тем не менее, спасибо за благодарность за наконечник эмулятора. – DarkOwl

+0

@Newbie yea мой синтаксис NASM немного ржавый try 'jmp word 0: begin' – Earlz

+0

Просто установил Bochs и загрузил исходный код учебника в него. Теперь формируется код каждого учебника! Вопрос в том, является ли мой phyiscal BIOS нестандартным, или это код? (Разумеется, все x86-совместимые BIOS должны соответствовать тем же стандартам ???) Я попробую ваши изменения на физическом BIOS моего ПК в любом случае. – DarkOwl

1

Я думаю, что проблема, вероятно, связана с указанным началом.

[ORG 0x7C00] ;Origin, tell the assembler that where the code will 

Основываясь на разговоре, у нас возникло впечатление, что адрес каким-то образом не предсказан. Возможно, DS-регистр регистра данных не соответствует ожидаемому. Вы могли бы на самом деле быть в состоянии получить исходный список с веб-страницы, чтобы работать, добавляя толчок и поп DS перед вызовом для отображения строки, как это,

push cs 
pop ds 

Если не следующий код работает.

[ORG 0x000] ; switched to 0 since we are going to try to correct it ourself 

call nextinstruction 
nextinstruction: ; get the return address of the call into dx 
pop dx    ; which is essentially the start of the code + 3 (3 bytes for the call instruction) 
MOV SI, HelloString ;Store string pointer to SI 
add si, dx   ; add IP from start of program 
sub si, 3   ; subtract the 3 the call instruction probably took 
push cs 
pop ds    ; make ds the same as cs. 
CALL PrintString ;Call print string procedure 
JMP $  ;Infinite loop, hang it here. 

Этот код выясняет, смещение во время выполнения этого кода, запуска, а также гарантирует, что DS является точка в том же сегменте. Если не указано иное, инструкции, касающиеся SI, также используют DS в качестве сегмента кода для ссылки на память.

DS - это регистр сегментов, и вы можете прочитать что-то вроде Art of Assembly, чтобы узнать больше.

Earlz также делает то же самое, просто убедившись, что регистры правильные, так что адрес памяти правильно указан. Просто он знает больше о специфике загрузочного сектора, чем мне.

+0

Как я уже сказал, учебник 2 отлично работает, доказывая, что BIOS настроен правильно для загрузки с дискеты. Это только тогда, когда ему говорят НИЧЕГО, НО ХАНГ (учебник 1), что BIOS игнорирует его. Я должен быть честным Я новичок в этой всей загрузке - этот урок - это все, что я сделал. Я предположил, что я * загружаюсь через загрузочный сектор - что заставляет вас думать, что я не? Кроме того, по мере того, как учебник исчерпан, программа скомпилируется с использованием NASM в необработанный двоичный файл (а не COM-файл). Но я дам ваше предложение попробовать в любом случае. – DarkOwl

+0

Верно, я неправильно истолковал то, что вы сказали. В этом случае я подозреваю, что происхождение по-прежнему является причиной проблемы, но выяснение фактической причины, вероятно, потребует распечатки регистра IP для определения фактического происхождения. Я посмотрю, смогу ли я придумать что-нибудь, чтобы помочь. –

+0

Хорошо, я пробовал ваше искушение. Я до сих пор не получаю «Hello World», но я тоже не получаю этого необычного персонажа. Я просто нажимаю мигающий курсор на верхний левый (в отличие от нижнего угла, где ранее был необычный персонаж). – DarkOwl

Смежные вопросы