KolibriOS: пробуем ассемблер
Решил потренироваться на ассемблере под x86 и выбор мой пал на KolibriOS. Ведь как-никак это ОС была написана на ассемблере и для использования ассемблера. И я хотел именно из самой KolibriOS писать код. Но... Наверное, зря я это всё затеял.
Как оказалось, примеров кода не мало и не много. А так как я привык к Dos, Windows или Linux, то и ожидал что-нибудь в этом роде. Код, код и ещё раз код. Макросы не так часто встречаются. Ну и уж точно не весь код из одних макросов (утрирую).
Пример кода из «официального источника» вносит больше сумятицы, чем понимания, что происходит в данном коде. И... там нет никакого объяснения этим «буквенным значениям». Есть только то, что ссылаются на файл «macros.inc». Если просматривать источники интернета, то где‑то более понятно написано и даже рассказывают, что взять «macros.inc» (и многие другие файлы) можно на SVN KolibriOS и, как оказалось, ещё можно на GitHub (зеркало).
Покопавшись в файле «macros.inc», а так же на просторах интернета и найдя пример (смотрите код Fasm), я понял, что всё становится на свои места и более‑менее проясняется.
Давайте начнём с того, что нам надо сначала запустить KolibriOS, ведь мы хотим программировать используя данную ОС. Зайдя в раздел скачивания и скачав один из образов KolibriOS, внутри архива разработчики предлагают несколько вариантов запуска ОС. Так же много вариантов запуска на просторах интернета, сложности, я думаю, не будет с этим.
Но я же сам уже давно решил для себя, что буду использовать Qemu для запуска ОС. И даже уже достаточно давно настроил и запустил.
скрипт для Linux
#!/bin/bash
qemu-system-x86_64
-enable-kvm
-cpu host,kvm=on
-smp 1,cores=1
-m 1G
-display gtk
-net nic,model=rtl8139 -net user
-hda kolibri.raw
-hdb kolibriOO.raw
-device VGA,vgamem_mb=128
-device ich9-intel-hda -device hda-duplex
А так все скрипты лежат под видео, уж извиняюсь.
Перейдём к коду, с официального сайта:
include "macros.inc"
MEOS_APP_START
CODE
redraw:
.....call draw_window
wait_event:
.....mcall 10
.....dec eax
.....jz redraw
.....dec eax
.....jz key;
button pressed; we have only one button, close
.....mcall -1
key:
; key pressed, read it and ignore
.....mcall 2
.....jmp wait_event
draw_window:
.....mcall 12, 1 ; start redraw
.....mcall 0, <10,150>, <40,50>, 0x33FFFFFF, , header ; define&draw window
.....mcall 4, <30,10>, 0x80000000, string ; display string
.....mcall 12, 2 ; end redraw
.....ret
DATA
header db 'HelloWorld test',0
string db 'Hello, World!',0
UDATA
MEOS_APP_END
теперь стоит обратить внимание на: MEOS_APP_START, CODE, DATA, UDATA, MEOS_APP_END и mcall - это всё макросы из файла "macros.inc". И, если mcall более-менее понятен (это как-бы системный вызов - прерывание int 40h), то что делает всё остальное объяснения практически не найти.
Если поковыряться в файле "macros.inc" и всё привести в более понятный вид, то получим вот такой код:
use32
__data:
org 0x0
db 'MENUET01'
dd 0x01
dd __start
dd __end
dd __memory
dd __stack
dd 0x0
dd 0x0
__start:
redraw:
.....call draw_window
wait_event:
.....mov eax, 10
.....int 0x40
.....dec eax
.....jz redraw
.....dec eax
.....jz key;
button pressed; we have only one button, close
.....mov eax, -1
.....int 0x40
key:
; key pressed, read it and ignore
.....mov eax, 2
.....int 0x40
.....jmp wait_event
draw_window:
.....mov eax, 12 ; start redraw
.....mov ebx, 1
.....int 0x40
.....mov eax, 0 ; define&draw window
.....mov ebx, <10, 150>
.....mov ecx, <40, 50>
.....mov edx, 0x33FFFFFF
.....mov edi, header
.....int 0x40
.....mov eax, 4 ; display string
.....mov ebx, <30, 10>
.....mov ecx, 0x80000000
.....mov edx, string
.....int 0x40
.....mov eax, 12 ; end redraw
.....mov ebx, 2
.....int 0x40
.....ret
IncludeIGlobals ; это внутренний макрос, я не стал в нём разбираться. Если кто-то разобрался в нём то просьба рассказать.
header db 'HelloWorld test',0
__end:
string db 'Hello, World!',0
align 32
rb 2048
__stack:
__memory:
Как видим, текста прибавилось, а для новичков код стал понятнее. Думаю, дальше сопоставить код сможет практически каждый. И также сможет теперь использовать макросы входящие в состав KolibriOS, и минимизировать свои программы, если будет использовать ассемблер. :)
комментарий
кстати, это стало похоже на код из официального источника, но только для Masm. Но я бы наверняка не обратил внимание сразу на это, ведь меня интересовало программирование в самой KolibriOS.
Разработчики KolibriOS позаботились о минимизации кода, но вот плохо что не позаботились над минимальным объяснением кода. В своё время они привлекли много людей для поддержки данной ОС, но многие закончили её использование и разработку под неё, а новички редко прикасаются к ассемблеру. Да как вы и видите сейчас даже для KolibriOS, стараются писать на ЯВУ, а не на ассемблере.
Давайте так же заглянем в отладчик поставляемый вместе с KolibriOS - Kolibri Debugger. Созданную нами программу можно запустить с помощью отладчика как из самого Fasm-а, так и с помощью текстовых редакторов TinyPad и CEdit. Сложности в отладке нет, если вы уже пользовались отладчиками. Но кому-то будет не понятно сразу как им пользоваться. Внизу в поле ввода введите help и вам отладчик вам выдаст следующие подсказки: help control, help data и help breakpoint. Думаю дальше вы сами справитесь, ведь большинство из вас лучше меня знают английский. :)
Для чего я это всё затеял? Я хотел потестировать ассемблерный код. Да, я периодически тестирую ассемблер, плюс узнаю что-нибудь новое, здесь я тестировал код для четырёх архитектур под Linux: Arm/Arm64/x86/x86_64. Но хотел я потестировать изначально под Dos и там код помучать, но видимо это будет позже.
Буду ли я дальше заниматься ассемблером под KolibriOS? Наверно да, на данный момент наверно не мало узнал по разработке под данную ОС. И, там видимо многое уже автоматизировано. На многих других ОС надо написать намного больше кода, чтоб получить графическое окно. Здесь же кода достаточно мало, и это на ассемблере! Интересно будет пощупать!
Успехов всем! ;)
комментарий
Прошу прощения за код, но как оказалось код не хочет правильно форматироваться.