Операционная система MenuetOS - Пример приложения под MenuetOS на примере файла EXAMPLE.ASM (original) (raw)
Статья немного устарела и скоро будет заменена, хотя все нижеизложенное работает. [Webmaster]
На дискете с Menuet'ом находится файл EXAMPLE.ASM. Это обычный пример - простое приложение в духе Hello World, для ознакомления с реальным, работающим кодом. Единственное, что оно делает - выводит в окно текстовое сообщение. Единственная кнопка - закрывает окно и заканчивает программу.
Этот пример можно использовать, как шаблон для написания собственных программ. Ниже код программы приведен целиком с комментариями на русском (комментарии располагаются в коде после символа точки с запятой - ';').
; EXAMPLE APPLICATION
; (пример приложения)
; Компилировать с помощью FASM для Menuet
use32 ;Директива компилятора - генерировать 32-битный код
org 0x0 ;Директива с аргуметом 0x0 - адресом, с которого
; код будет начинаться в памяти
db 'MENUET00' ; 8-байтовый идентефикатор
dd 38 ; требуемая версия ОС
dd START ; указывает начало программы
dd I_END ; метка в конце кода, указывающая размер программы
dd 0x100000 ; требуемое количество оперативной памяти
dd 0x00000000 ;зарезервировано=не расширенный заголовок (?)
START: ; Начинаем исполнение программы здесь
call draw_window ;Для начала нарисуем окно.
;Инструкция call - вызывает подпрограмму, расположенную
;после метки draw_window
;Сама метка, когда она появляется в коде,
;заканчивается двоеточием (см. выше метку START, например)
still: ;Здесь начало кода для обработки событий
mov eax,10 ;10 - номер системной фунции "ждать события"
;Записываем этот аргумент в регистр eax
int 0x40 ;А теперь вызываем саму эту функцию.
;Поскольку она системная, то и выполняется системой.
;Она вызывается с помощью прерывания (инструкция int)
;С помощью этого прерывания (0x40) выполняются все системные
;функции (их список есть в файле SYSFUNCS.TXT
;Когда произойдет событие (нажатие клавиши,
;запрос на перерисовку и т.п.)
;код продолжит исполняться с этого самого места, а в регистр eax
;будет записано значение, указывающее на тип произошедшего события.
;Начинаем определять, какое произошло событие:
cmp eax,1 ;Запрос ли на перерисовку?
je red ;Если так, то переходим к метке red
cmp eax,2 ;Или нажата клавиша?
je key ;Тогда идем к метке key
cmp eax,3 ;или же нажата кнопка (нарисованная в окне приложения)?
je button ;Тогда - к метке button
jmp still ;Других вариантов нет - возварщаемся к still,
;чтобы ожидать новых событий
red: ;Перерисовка окна...
call draw_window ;просто вызываем функцию перерисовки окна...
jmp still ;и возвращаемся ждать событий
key: ;Нажата клавиша
mov eax,2 ;Cистемная функция номер 2 - прочитать код нажатой клавиши...
int 0x40 ;Вызываем эту фунцию, а ее ответ игнорируем.
jmp still ;И возвращаемся ждать событий
button: ;Нажата кнопка в окне программы.
mov eax,17 ;Функция номер 17 - спрашиваем систему,
;какая именно кнопка нажата;
int 0x40 ;она вернет идентефикатор кнопки в регистре ah
cmp ah,1 ;Сравним содержимое ah со значением "1"
jne noclose ;Если НЕ нажата кнопка с id равным 1,
;то идем к метке nonclose
mov eax,-1 ;иначе - завершаем программу вызовом функции "-1"...
int 0x40 ;вот этот вызов
noclose: ;Кнопка "выход" не нажата:
jmp still ;просто возвращаемся ждать события
; *********************************************
; **** ОПРЕДЕЛЕНИЕ И ОТРИСОВКА ОКНА ********
; *********************************************
draw_window: ;Здесь мы начинаем подпрограмму рисования окна
mov eax,12 ;Функция 12: сообщить ОС об отрисовке окна
mov ebx,1 ;Параметр функции (1) в регистре ebx - начинаем рисовать
int 0x40 ;Вызов функции
;НАЧИНАЕМ СОБСТВЕННО РИСОВАНИЕ
mov eax,0 ;Функция 0 : определить и нарисовать окно
mov ebx,100*65536+300 ;Координата начала окна по оси x *65536
;+ ширина окна,
; то есть окно шириной 300 (пикселей) начинается на сотом
mov ecx,100*65536+120 ;Аналогично - начало по y (*65536) + высота окна
mov edx,0x001111cc ;Цвет рабочей области окна
mov esi,0x8099bbff ;Цвет полосы заголовка RRGGBB,8->color glide (?)
mov edi,0x00ffffff ;Цвет рамки RRGGBB
;RRGGBB означает, что два байта RR кодируют красный (Red) цвет
;и еще по два байта на зеленый (Green) и синий (Blue)
int 0x40 ;Параметры функии подготовили и вызываем ее.
;ЗАГОЛОВОК ОКНА
mov eax,4 ;Функция 4 : написать в окне текст
mov ebx,8*65536+8 ;[начало по оси x ] *65536 + [начало по y]
mov ecx,0x00ffffff ;Цвет текста RRGGBB (про RGB - см.выше)
mov edx,labelt ;Пишем в регистр edx указатель на начало текста,
mov esi,labellen-labelt ; а в esi - длина текста в байтах
int 0x40 ;вызываем систему (т.е. системную функцию)
; КНОПКА ДЛЯ ВЫХОДА
mov eax,8 ;Функция 8 : определить и нарисовать кнопку
mov ebx,(300-19)*65536+12 ;[начало по x]*65536 + [размер по x (ширина)]
mov ecx,5*65536+12 ;[начало по y] *65536 + [высота]
mov edx,1 ;Идентефикатор (id) данной кнопки
mov esi,0x5599cc ;Цвет кнопки RRGGBB
int 0x40 ;Вызываем функцию 8, параметры которой уже в регистрах...
; Выводим сообщение с помощью функции 4
mov ebx,25*65536+35 ;координаты точки, начиная с которой выводить текст
;25 по оси x и 35 по оси y
mov ecx,0xffffff ;Цвет текста
mov edx,text ;Указатель на текст (сам текст см. ниже)
mov esi,40 ;длина текста - 40 байт
newline: ;...см.ниже
mov eax,4 ;Функция 4 - вывод текста в окно
int 0x40 ;Вызываем функцию = пишем одну строку
add ebx,10 ;Добавляем к ebx,10, чтобы в следующую строку
;рисовать на 10 пикселей ниже
add edx,40 ;Добавляем к edx 40, чтобы брать символы
;очередной строки
;начиная с адреса, который уже в edx (указатель text),
;но еще на 40 символов (байт) дальше.
;Таким образом мы выводим
;ровно строки по 40 символов.
cmp [edx],byte 'x' ;Обращаемся по получившемуся адресу (регистр edx)...
; и смотрим, что там за байт.
jne newline ; Если это НЕ байт со значенем 'x', то продолжаем
;цикл вывода строк,
;то есть мы узнали, что это не последняя строка, и переходим к
;метке newline, чтобы вывести ее, используя подготовленные параметры
;в регистрах edx, ebx и т.д.
;То есть подразумеваем договоренность о том, что встретившийся
;в начале строки символ 'x' скажет нам закончить печать
mov eax,12 ;Функция 12 :сообщить ОС об отрисовке окна
mov ebx,2 ;Параметр этой функции равный 2... заканчили рисование
int 0x40 ;вызываем 12-ую функцию
ret ;от англ. return - возвращаться. То есть мы возвращаемся
;из подпрограммы рисования окна, которая была вызвана
;инструкцией call
; ЗДЕСЬ НАЧИНАЕТСЯ РАЗДЕЛ ДАННЫХ
text: ;эта метка указывает на выводимый текст:
db 'THIS IS AN EXAMPLE PROGRAM YOU COULD '
db 'USE, A:\EXAMPLE.ASM CODE IS COMMENTED '
db 'AND CLEAR. SYSTEM FUNCTIONS ARE IN FILE '
db 'SYSFUNCS.TXT AND COMMANDS IN CMD.TXT '
db 'x <- НЕ УДАЛЯТЬ! МАРКЕР КОНЦА '
; инструкциями db мы добавили в код
;последовательности данных (d), конкретнее байт (b)