Почему не хочет выводить строчку?
Всем привет! Пытаюсь сделать лабу, и надо запустить загрузчик и ядро, делаю все по методичке но ничего не получается, помогите в чем ошибка?
Команда на qemu: qemu-system-x86_64 -fda bootsect.bin -fdb kernel.bin
Код загрузчика:
use16
org 0x7c00
start:
; Инициализация адресов сегментов. Эти операции требуется не для любого BIOS, но их рекомендуется проводить.
mov ax, cs ; Сохранение адреса сегмента кода в ax
mov ds, ax ; Сохранение этого адреса как начало сегмента данных
mov ss, ax ; И сегмента стека
mov sp, start ; Сохранение адреса стека как адрес первой инструкции этого кода. Стек будет расти вверх и не перекроет код.
mov ah, 0
mov al, 2
int 0x10
mov ah, 0x0e ; В ah номер функции BIOS: 0x0e - вывод символа на активную видео страницу (эмуляция телетайпа)
mov al, 'H' ; В al помещается код символа
int 0x10 ; Вызывается прерывание. Обработчиком является код BIOS. Символ будет выведен на экран.
mov al, 'e'
int 0x10
mov al, 'l'
int 0x10
int 0x10
mov al, 'o'
int 0x10
mov ax, 0x1000
mov es, ax
mov ax, 0x0000
mov bx, ax
mov dl, 0x01 ;номер диска
mov dh, 0x00 ;номер головки
mov cl, 0x01 ;номер сектора
mov ch, 0x00 ;номер цилиндра
mov al, 1 ;количество секторов
mov ah, 0x02
int 0x13
; Отключение прерываний
cli
; Загрузка размера и адреса таблицы дескрипторов
lgdt [gdt_info] ; Для GNU assembler должно быть "lgdt gdt_info"
; Включение адресной линии А20
in al, 0x92
or al, 2
out 0x92, al
; Установка бита PE регистра CR0 - процессор перейдет в защищенный режим
mov eax, cr0
or al, 1
mov cr0, eax
jmp 0x8:protected_mode ; "Дальний" переход для загрузки корректной информации в cs (архитектурные особенности не позволяют этого сделать напрямую).
gdt:
; Нулевой дескриптор
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
; Сегмент кода: base=0, size=4Gb, P=1, DPL=0, S=1(user),
; Type=1(code), Access=00A, G=1, B=32bit
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
; Сегмент данных: base=0, size=4Gb, P=1, DPL=0, S=1(user),
; Type=0(data), Access=0W0, G=1, B=32bit
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
gdt_info: ; Данные о таблице GDT (размер, положение в памяти)
dw gdt_info - gdt ; Размер таблицы (2 байта)
dw gdt, 0 ; 32-битный физический адрес таблицы.
use32
protected_mode:
; Здесь идут первые инструкции в защищенном режиме
; Загрузка селекторов сегментов для стека и данных в регистры
mov ax, 0x10 ; Используется дескриптор с номером 2 в GDT
mov es, ax
mov ds, ax
mov ss, ax
; Передача управления загруженному ядру
call 0x00011000 [1]; Адрес равен адресу загрузки в случае если ядро скомпилировано в "плоский" код
; Внимание! Сектор будет считаться загрузочным, если содержит в конце своих 512 байтов два следующих байта: 0x55 и 0xAA
times (512 - ($ - start) - 2) db 0 ; Заполнение нулями до границы 512- 2 текущей точки
db 0x55, 0xAA ; 2 необходимых байта чтобы сектор считался загрузочным
Код Ядра:
extern "C" int kmain();
__declspec(naked) void startup()
{
__asm {
call kmain;
}
}
#define VIDEO_BUF_PTR (0xb8000)
void out_str(int color, const char* ptr, unsigned int strnum)
{
unsigned char* video_buf = (unsigned char*)VIDEO_BUF_PTR;
video_buf += 80 * 2 * strnum;
while (*ptr)
{
video_buf[0] = (unsigned char)*ptr; // Символ (код)
video_buf[1] = color; // Цвет символа и фона
video_buf += 2;
ptr++;
}
}
const char* g_test = "This is test string.";
extern "C" int kmain()
{
const char* hello = "Welcome to HelloWorldOS (gcc edition)!";
// Вывод строки
out_str(0x07, hello, 0);
out_str(0x07, g_test, 1);
// Бесконечный цикл
while (1)
{
__asm hlt;
}
return 0;
}
Транслятор FASM,компилятор ms c compiler.
- Что должно выводиться на экран системы?
- Welcome to HelloWorldOS (gcc edition)! Но почему то не выводится
- [1] Откуда узнала адрес?
- С помощью функции:
dumpbin /headers kernel.bin
, где было написано:
SECTION HEADER #1
.text name
AE virtual size
1000 virtual address (00011000 to 000110AD)
200 size of raw data
200 file pointer to raw data (00000200 to 000003FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
Execute Read
SECTION HEADER #2
.data name
E8 virtual size
2000 virtual address (00012000 to 000120E7)
200 size of raw data
400 file pointer to raw data (00000400 to 000005FF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read Write
Оттуда и взяла. Еще раз дублирую вопрос почему не выводит строчку Welcome to HelloWorldOS (gcc edition)!
?
Источник: Stack Overflow на русском