;--------------------------------------------------------------------- use32 ; включить 32-битный режим ассемблера org 0 ; адресация с нуля db 'MENUET01' ; 8-байтный идентификатор MenuetOS dd 1 ; версия заголовка (1 либо 2, см. док-ю) dd START ; адрес первой команды dd I_END ; размер программы dd MEM ; количество памяти dd STACKTOP ; адрес вершины стэка dd 0 ; адрес буфера для параметров dd 0 ; зарезервировано include "macros.inc" ; макросы облегчают жизнь ассемблерщиков! ;--------------------------------------------------------------------- ;--- НАЧАЛО ПРОГРАММЫ ---------------------------------------------- ;--------------------------------------------------------------------- START: mov [mposX], 1 mov [mposY], 1 mov eax, 40 mov ebx, 100111b int 0x40 red: ; перерисовать окно call draw_window ; вызываем процедуру отрисовки окна ;--------------------------------------------------------------------- ;--- ЦИКЛ ОБРАБОТКИ СОБЫТИЙ ---------------------------------------- ;--------------------------------------------------------------------- still: mcall 10 ; функция 10 - ждать события cmp eax,1 ; перерисовать окно ? je red ; если да - на метку red cmp eax,2 je key cmp eax,3 ; нажата кнопка ? je button ; если да - на button cmp eax,6 ; нажата клавиша ? je mouse ; если да - на key jmp still ; если другое событие - в начало цикла ;--------------------------------------------------------------------- key:; нажата клавиша на клавиатуре ; функция 2 - считать код символа (в ah) mcall 2 call draw_window ; вызываем процедуру отрисовки окна jmp still ; вернуться к началу цикла mouse:; нажата клавиша на клавиатуре ; функция 2 - считать код символа (в ah) mcall 37,0 mov ecx, eax mov [mposY],cx shr ecx, 16 mov [mposX],cx mcall 37,3 mov [mst], eax ;cmp eax,1 ; перерисовать окно ? ;and eax, 00010b and eax, 0x200 jz rds ;jne rds mov edx, 16 shl edx, 16 mov dx, 16 ;neg [mposX] ;neg [mposY] ;mov edx, eax ;add edx, ecx mcall 18,19, 4 ; записать код символа из регистра ah в память rds: call draw_window ; вызываем процедуру отрисовки окна jmp still ; вернуться к началу цикла ;--------------------------------------------------------------------- button: mcall 17 ; 17 - получить идентификатор нажатой кнопки cmp ah, 1 ; если НЕ нажата кнопка с номером 1, jne still ; вернуться .exit: mcall -1 ; иначе конец программы ;--------------------------------------------------------------------- ;--- ОПРЕДЕЛЕНИЕ И ОТРИСОВКА ОКНА ---------------------------------- ;--------------------------------------------------------------------- draw_window: mcall 12, 1 ; функция 12: сообщить ОС о начале отрисовки mcall 48, 3, sc,sizeof.system_colors mov edx, [sc.work] ; цвет фона or edx, 0x33000000 ; и тип окна 3 mcall 0, <200,300>, <200,150>, , ,title mov edx, 50*65536+40 mov eax, 47 mov ebx, 0x80080000 mov ecx, 0 mov cx,[mposY] mov esi, [sc.work_text] ; цвет фона or esi, 0x10000000 int 0x40 mov edx, 50*65536+20 mov eax, 47 mov ebx, 0x80080000 mov ecx, 0 mov cx,[mposX] mov esi, [sc.work_text] ; цвет фона or esi, 0x10000000 int 0x40 mov edx, 50*65536+60 mov eax, 47 mov ebx, 0x001F0200 mov ecx, dword[mst] mov esi, [sc.work_text] ; цвет фона or esi, 0x10000000 int 0x40 ; вывод текстовой строки mov ecx, [sc.work_text] ; цвет фона or ecx, 0x90000000 ; и тип строки mcall 4, <10, 20>, , message mov ecx, [sc.work_text] ; цвет фона or ecx, 0x90000000 ; и тип строки mcall 4, <10, 40>, , message2 mcall 12, 2 ; функция 12.2, закончили рисовать ret ; выходим из процедуры ;--------------------------------------------------------------------- ;--- ДАННЫЕ ПРОГРАММЫ ---------------------------------------------- ;--------------------------------------------------------------------- ; Вот такая вот короткая "мелодия". ; Второй байт изменяется нажатием клавишы sc system_colors message db 'X:',0 message2 db 'Y:',0 mposX rw 1 mposY rw 1 mst rd 1 title db 'Пример программы',0 ;--------------------------------------------------------------------- I_END: ; метка конца программы rb 4096 ; память для стека align 16 STACKTOP: ; метка вершины стека (при заполнении стек ; растет в сторону уменьшения адресов, потому ; память для него в коде программы встречается ; раньше чем его вершина) MEM: ; метка указывающая на конец программы плюс ; размер используемой ею оперативной памяти ; Адрес метки MEM всегда должен быть больше чем адрес метки I_END. ; Метка STACKTOP должна располагается после метки I_END и перед меткой ; MEM. STACKTOP может находится и перед I_END, но это не правильно. ; Имена меток могут быть с любыми названиями, главное соблюдать ; правильный порядок их расположения.