Доброго дня, уважаемые читатели. В статье начнем писать ядро операционной системы. В предыдущей статье был подготовлен загрузчик для нашей Simple OS. Однако чистый черный экран не вызывал чувства исполненного долга. В качестве первого шага я напишу на ассемблере строку с названием операционной системы и версию ядра. Предположим что текущая версия — 0.0.1. Значит нужно вывести на экран следующую строку:

Simple OS, version 0.0.1

Увы, знания о выводе строк на экран средствами BIOS больше не помогут. Они остались в прошлом, в режиме реальных адресов. В суровой действительности защищённого режима вывести текст на экран поможет лишь прямая запись в видеопамять.

Видеопамять

видео карта - ядро операционной системы

Видеопамять — это внутренняя память, предназначенная для хранения данных изображения, которое выводится на экран. Адрес начала видеопамяти в текстовом режиме для цветных мониторов: 0xB8000, а для монохромных: 0xB0000. Каждый символ кодируется двумя байтами. Первый байт это ASCII-код символа. Второй вмещает в себя в младших 4-х битах цвет текста, в старших 3-х битах цвет фона и в последнем бите — конфигурацию оборудования.

Если в байт атрибута будет установлено, например, значение 0x1F, то на экран выведутся белые символы на синем фоне. Пользователям Windows знакомо такое сочетание цветов :).

синий экран смерти - ядро операционной системы

Но мы будем пользоваться другим цветом. В DOS используется сочетание светло-серый шрифт на черном фоне. Примем значение 0x07 временно за эталон.

Очистка экрана

С очисткой экрана, думаю, все просто. Нам надо заполнить весь экран пробелами — ‘ ‘. Длина массива данных для формирования изображения высчитывается по простой формуле:

80 символов * 25 строк * 2 байта = 4000 байт

 mov ebx,0xB8000 
    mov dx, 0

clean:
    cmp dx, 4000
    je done_clean
    mov al, ' '
    mov ah, 0x07
    mov [ebx], ax
    add ebx, 2
    add dx, 2
    jmp clean

done_clean:

Как видно в коде, в регистр ebx (помним что сейчас мы работаем в 32-битной среде) нужно поместить значение адреса начала видеопамяти — 0xB8000. В цикле помещаем нужные значения в регистры: al — символ пробела, а в ah — цвет. Далее помещаем значение ax по адресу, хранимому в ebx. Увеличиваем значение адреса и регистр цикла dx на 2, возвращаемся и повторяем процедуру пока dx не станет равен 4000. Профит!

экран очищен

Вывод текста

Теперь делаем практически то же самое для текста:

mov ebx,0xB8000
    mov edx,OS_DETAILS	

print:
    mov al,[edx] 
    cmp al, 0
    je done
    mov ah,0x07
    mov [ebx],ax
    add ebx, 2
    add edx, 1
    jmp print
    
done:
    hlt 
OS_DETAILS: db 'Simple OS, version 0.0.1', 0
ядро операционной системы

Код полностью

Хочу пояснить, что код выше исполняется, как ядро операционной системы. И оно уже отвечает нам, пусть и немудрено. Чтобы не оставалось вопросов приведу полный код вместе с загрузчиком.

section .multiboot_header
header_start:
    dd 0xE85250d6                
    dd 0                         
    dd header_end - header_start 
    dd 0x100000000 - (0xE85250D6 + 0 + (header_end - header_start))
    dw 0    
    dw 0    
    dd 8    

header_end:
section .text
bits 32	
global start

start:
    cli 			
    mov esp, stack_space
    mov ebx,0xB8000 
    mov dx, 0

clean:
    cmp dx, 4000
    je done_clean
    mov al, ' '
    mov ah, 0x07
    mov [ebx], ax
    add ebx, 2
    add dx, 2
    jmp clean

done_clean:
    mov ebx,0xB8000
    mov edx,OS_DETAILS	

print:
    mov al,[edx] 
    cmp al, 0
    je done
    mov ah,0x07
    mov [ebx],ax
    add ebx, 2
    add edx, 1
    jmp print
    
done:
    hlt
    
OS_DETAILS: db 'Simple OS, version 0.0.1', 0	 	
    
section .bss
resb 8192		
stack_space:

Надеюсь , что вам так же интересно как и мне. Вскоре мы постараемся вырваться из оков ассемблера и подняться на уровень выше! До свидания!

Канал в Яндекс.Дзен

Картинки видеокарты и синего экрана найдены на просторах интернета.