Исправил и подробно разжевал пример по ссылке выше, а вообще, прежде чем что-то рекомендовать новичкам лучше лишний раз убедиться в правильности кода:
Код:
;заголовок приложения (в любой программе для колибри выглядит примерно так)
use32 ; сообщим фасму, что собираемся использовать 32 битные команды
org 0x0 ; базовый адрес кода (всегда 0x0)
db 'MENUET01' ; идентификатор исполняемого файла Колибри (наследие от предка - MenuetOS - всегда 'MENUET01')
dd 0x1 ; версия формата заголовка исполняемого файла (всегда 0x1)
dd start ; указывает откуда начинается сам код программы
dd i_end ; указывает, где этот код заканчивается
dd i_end ; объем используемой памяти (здесь объем памяти равен объему кода, потому строка указывает на тот же адрес, что и предыдущая)
dd i_end+0x100 ; вершина стека (стек растет снизу вверх от указанной величины в сторону данных программы, здесь выбран размер стека 0x100)
dd 0x0,0x0 ; через запятую: указатель на строку с параметрами и указатель на строку, куда помещается путь к данной программе на диске
; тут вбиты нули - это означает, что мы не отслеживаем в программе эти данные.
;----------------------------------------------------------------------------------------
align 4 ; выравнивание кода
start: ; здесь начинается сама программа
; mov eax,40 ; вызов системной функции 40: установить маску для ожидаемых событий (полный список функций см. в sysfuncr.txt описание событий в конце документа)
; mov ebx,0x7 ; программа будет реагировать только на события, которые мы разрешим этой функцией.
; int 0x40 ; По умолчанию ( если эту функцию не вызывать) программе будут приходить сообщения о нажатии кнопки в программе,
; о необходимости перерисовать окно и о нажатии какой-либо клавиши на клавиатуре,
; что достаточно для этой программы, поэтому вызов функции закомментирован)
red_win: ; рисуем окно программы
call draw_window ; вызов процедуры draw_window (см. ниже)
still: ; нарисовали - переходим в основной цикл программы
mov eax,10 ; функция 10: ждем события, которые мы выше определили функцией 40
int 0x40
; событие произошло, теперь проверяем, какое именно
cmp al,0x1 ; если система говорит, что нужно перерисовать окно (изменились его размер или положение)
jz red_win ; перепрыгиваем на процедуру red_win (перерисовываем окно) и ждем события дальше
cmp al,0x3 ; если была нажата кнопка в программе,
jz button ; то прыгаем на процедуру button
key: ; если это и не кнопка и не перерисовка, значит остается одно - клавиша на клавиатуре
mov eax,2 ; функция 2: считываем код нажатой клавиши и забываем, потому как мы не используем клавиатуру в этой программе
int 0x40
jmp still ; сделали свое дело и опять возвращаемся в основной цикл программы и ждем событий
button: ; процедура обрабоки кнопок в программе
mov eax,17 ; функция 17: получить номер нажатой кнопки
int 0x40
shr eax,8 ; сдвигаем регистр eax на 8 бит вправо, чтобы получить номер нажатой кнопки
cmp eax,1
jne no_exit ; если это не кнопка 1 (зарезервирована системой как кнопка закрытия программы), пропускаем 2 следующие строчки кода
or eax,-1 ;(равносильно команде mov eax,-1, но более оптимально - функция -1: завершение программы)
int 0x40
no_exit: ; и переходим сюда, где проверяем, какая же все таки кнопка была нажата (в этой программе других кнопок нет,
jmp still ; поэтому возвращаемся в основной цикл программы и опять ждем событий)
draw_window: ; процедура отрисовки окна приложения
mov eax,12 ; функция 12,
mov ebx,1 ; подфункция 1: сообщить системе, что мы хотим нарисовать окно
int 0x40
xor eax,eax ; обнуляет регистр eax (по сути - то же, что и mov eax,0, но более оптимально) - функция 0: нарисовать окно
mov ebx,50*65536+180 ; [координата окна по оси x]*65536 + [размер по оси x]
mov ecx,30*65536+100 ; [координата по оси y]*65536 + [размер по оси y]
mov edx,0x33AABBCC ; цвет рабочей области окна RRGGBB, первые 2 цифры (33) определяют тип и параметры окна,
; тут - 3 тип (окно со скином изменяемого размера) и координнаты окна отсчитываются он клиентской области
mov edi,hed ; заголовок программы
int 0x40
; здесь рисуются все основные элементы программы, если они есть, в нашем случае это просто пустое окно
mov eax,12 ; функция 12,
mov ebx,2 ; подфункция 2 - сообщить системе, что мы закончили отрисовку окна.
int 0x40
ret
hed db 'Hello World',0 ; название программы
i_end: