Загрузчик с графикой (NASM) - PullRequest
4 голосов
/ 31 марта 2012

Я написал простой загрузчик на основе: http://www.viralpatel.net/taj/tutorial/hello_world_bootloader.php

[BITS 16]   ;16bit
[ORG 0x7C00]    ;offset

MOV AH, 0x00 ; change video mode
MOV AL, 0x13 ; 0x13
INT 0x10 ; interrupt
CALL DrawTenLines   ;lets draw
JMP $       ;hang it

DrawOneLine:
MOV CX, 0x00 ;x = 0

nextpixel:
MOV AH, 0x09 ;func number - WritePixelOnScreen [wiki]
MOV AL, 0x05 ;color - Magenta
MOV BH, 0x00 ;Page no
INT 0x10 ;Video interrupt - BIOS
CMP CX, 10 ;if (x == 10) {
JE exitfunc ;exit function } else {
JNE nextpixel ;next pixel }
ADD CX, 0x01 ;add one :D
exitfunc: ;exit :D
RET

DrawTenLines: ;draw some lines
MOV DX, 0x00 ;y = 0
CALL DrawOneLine
MOV DX, 0x01 ;y = 1
CALL DrawOneLine
MOV DX, 0x02 ;y = 2
CALL DrawOneLine
MOV DX, 0x03 ;y = 3
CALL DrawOneLine
MOV DX, 0x04 ;y = 4
CALL DrawOneLine
MOV DX, 0x05 ;y = 5
CALL DrawOneLine
RET

;Data

TIMES 510 - ($ - $$) db 0   ;Fillers
DW 0xAA55           ;boot signature

Но это работает не так, как ожидалось - не рисует, только черный экран и зависает (как и ожидалось).

Скомпилировано с NASM, -f bin.Пример с этого сайта работает.Протестировано в Virtualbox.

РЕДАКТИРОВАТЬ: Забыли изменить режим видео - но все еще не работает.

РЕДАКТИРОВАТЬ 2: Этот код: [БИТЫ 16]; 16 бит [ORG 0x7C00]; смещение

MOV AH, 0x00
MOV AL, 0x13
INT 0x10
MOV AH, 0x09 ;WritePixelOnScreen [wiki]
MOV AL, 0x0F ;color - White
MOV BH, 0x00 ;page no. 
MOV CX, 1 ;x
MOV DX, 1 ;y
INT 0x10 ;interrupt
MOV CX, 2 ;x
MOV DX, 1 ;y
INT 0x10 ;interrupt
MOV CX, 3 ;x
MOV DX, 1 ;y
INT 0x10 ;interrupt
JMP $       ;hang

;Data

TIMES 510 - ($ - $$) db 0   ;filler
DW 0xAA55           ;boot signature

Производит: http://i.imgur.com/UGS3m.png

Ответы [ 2 ]

2 голосов
/ 31 марта 2012

У вас есть бесконечный цикл в DrawOneLine.Эта строка никогда не выполняется:

ADD CX, 0x01 ;add one :D

Ваш код зацикливания должен выглядеть примерно так:

CMP CX, 10 ;if (x == 10) {
JE exitfunc ;exit function } else {
ADD CX, 0x01 ;add one :D
JMP nextpixel ;next pixel }

Я думаю, что ваша проблема может быть в неправильном режиме видео.Вы устанавливаете режим видео в режим 0x13, а затем вызываете INT 0x10, AH=0x09, что, я считаю, является функцией текстового режима.IIRC, экранные данные для режима 0x13 расположены по адресу 0xA000: 0x0000, и вы можете писать в него напрямую.

РЕДАКТИРОВАТЬ: Я думаю, INT 0x10, AH=0x0C - это то, что вы пытались использовать, вместо INT 0x10, AH=0x09.

1 голос
/ 31 марта 2012

Краткий ответ: я думаю, что эти 2 строки:

MOV CX, [EAX] ;x
MOV DX, [EBX] ;y

должны быть:

MOV CX, AX ;x
MOV DX, BX ;y

(без квадратных скобок, используйте младшие 16 бит).

Более длинный ответ: я не думаю, что код висит там, где вы думаете.Я ожидаю, что он зависнет из-за этих двух строк:

MOV CX, [EAX] ;x
MOV DX, [EBX] ;y

Ваши комментарии кода указывают, что вы понимаете C, поэтому я объясню в этих терминах.Инструкции:

MOV EAX, 0x00
MOV CX, [EAX]

эквивалентны:

unsigned int EAX = 0;
unsigned short CX;
CX = (unsigned short)(*EAX);

У меня может быть неправильное наложение.Дело в том, что при заключении скобок в EAX («[EAX]») содержимое EAX используется в качестве указателя.Я ожидаю, что ваш код разыменует указатель NULL, который может вызывать зависание.

EDIT, в соответствии с вашим обновлением

Вы пытаетесь записать пиксель наэкран с использованием этого прерывания:

MOV AH, 0x09 ;func number - WritePixelOnScreen [wiki]
MOV AL, 0x05 ;color - Magenta
MOV BH, 0x00 ;Page no
INT 0x10 ;Video interrupt - BIOS

Я не вижу там никаких параметров координат.Я просмотрел функции int 10h и обнаружил, что AH = 09h - это «запись символа и атрибута в позиции курсора» - не то, что вы хотите.Посмотрите на AH = 0Ch - «изменить цвет для одного пикселя» .Эта ссылка имеет короткий пример, демонстрирующий правильное использование.

...