Ассемблер для Windows


         

Приступаем к разбору следующего примера - часть 2


;----структура класса окон WNDCLASS STRUC CLSSTYLE DD ? CLWNDPROC DD ? CLSCBCLSEX DD ? CLSCBWNDEX DD ? CLSHINST DD ? CLSHICON DD ? CLSHCURSOR DD ? CLBKGROUND DD ? CLMENNAME DD ? CLNAME DD ? WNDCLASS ENDS

; файл button.asm .386P ; плоская модель .MODEL FLAT, stdcall include button.inc ; директивы компоновщику для подключения библиотек includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ;------------------------------------------------------------ ; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' NEWHWND DD 0 MSG MSGSTRUCT <?> WC WNDCLASS <?> HINST DD 0 ; дескриптор приложения TITLENAME DB 'Пример - кнопка выхода',0 CLASSNAME DB 'CLASS32',0 CPBUT DB 'Выход',0 ; выход CLSBUTN DB 'BUTTON',0 HWNDBTN DWORD 0 CAP DB 'Сообщение',0 MES DB 'Конец работы Программы',0 _DATA ENDS

; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' START: ; получить дескриптор приложения PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX REG_CLASS: ; заполнить структуру окна ; стиль MOV [WC.CLSSTYLE], STYLE ; процедура обработки сообщений MOV [WC.CLWNDPROC], OFFSET WNDPROC MOV [WC.CLSCBCLSEX], 0 MOV [WC.CLSCBWNDEX], 0 MOV EAX, [HINST] MOV [WC.CLSHINST], EAX ;---------- иконка окна PUSH IDI_APPLICATION PUSH 0 CALL LoadIconA@8 MOV [WC.CLSHICON], EAX ;---------- курсор окна PUSH IDC_ARROW PUSH 0 CALL LoadCursorA@8 MOV [WC.CLSHCURSOR], EAX ;---------- MOV [WC.CLBKGROUND], 17 ; цвет окна MOV DWORD PTR [WC.CLMENNAME],0 MOV DWORD PTR [WC.CLNAME],OFFSET CLASSNAME PUSH OFFSET WC CALL RegisterClassA@4 ; создать окно зарегистрированного класса PUSH 0 PUSH [HINST] PUSH 0 PUSH 0 PUSH 400 ; DY - высота окна PUSH 400 ; DX - ширина окна PUSH 100 ; Y - координата левого верхнего угла PUSH 100 ; X - координата левого верхнего угла PUSH WS_OVERLAPPEDWINDOW PUSH OFFSET TITLENAME ; имя окна PUSH OFFSET CLASSNAME ; имя класса PUSH 0 CALL CreateWindowExA@48 ; проверка на ошибку CMP EAX, 0 JZ _ERR MOV [NEWHWND], EAX ; дескриптор окна ;-------------------------------------------------- PUSH SW_SHOWNORMAL PUSH [NEWHWND] CALL ShowWindow@8 ; показать созданное окно ;-------------------------------------------------- PUSH [NEWHWND] CALL UpdateWindow@4 ; команда перерисовать видимую ; часть окна, сообщение WM_PAINT ; петля обработки сообщений MSG_LOOP: PUSH 0 PUSH 0 PUSH 0 PUSH OFFSET MSG CALL GetMessageA@16 CMP EAX, 0 JE END_LOOP PUSH OFFSET MSG CALL TranslateMessage@4 PUSH OFFSET MSG CALL DispatchMessageA@4 JMP MSG_LOOP END_LOOP: ; выход из программы (закрыть процесс) PUSH [MSG.MSWPARAM] CALL ExitProcess@4 _ERR: JMP END_LOOP ;---------------------------------------------------------- ; процедура окна ; расположение параметров в стеке ; [EBP+014Н] ; LPARAM ; [EBP+10H] ; WAPARAM ; [EBP+0CH] ;MES ; [EBP+8] ;HWND WNDPROC PROC PUSH EBP MOV EBP,ESP PUSH EBX PUSH ESI PUSH EDI CMP DWORD PTR [EBP+0CH], WM_DESTROY JE WMDESTROY CMP DWORD PTR [EBP+0CH], WM_CREATE JE WMCREATE CMP DWORD PTR [EBP+0CH], WM_COMMAND JE WMCOMMND JMP DEFWNDPROC WMCOMMND: MOV EAX, HWNDBTN CMP DWORD PTR [EBP+14H], EAX ; не кнопка ли нажата? JE WMDESTROY MOV EAX, 0 JMP FINISH WMCREATE: ; создать окно-кнопку PUSH 0 PUSH [HINST] PUSH 0 PUSH DWORD PTR [EBP+08H] PUSH 20 ; DY PUSH 60 ; DX PUSH 10 ; Y PUSH 10 ; X PUSH STYLBTN PUSH OFFSET CPBUT ; имя окна PUSH OFFSET CLSBUTN ; имя класса PUSH 0 CALL CreateWindowExA@48 MOV HWNDBTN, EAX ; запомнить дескриптор кнопки MOV EAX, 0 JMP FINISH DEFWNDPROC: PUSH DWORD PTR [EBP+14H] PUSH DWORD PTR [EBP+10H] PUSH DWORD PTR [EBP+0CH] PUSH DWORD PTR [EBP+08H] CALL DefWindowProcA@16 JMP FINISH WMDESTROY: PUSH 0 ; MB_OK PUSH OFFSET CAP PUSH OFFSET MES PUSH DWORD PTR [EBP+08H] ; дескриптор окна CALL MessageBoxA@16 PUSH 0 CALL PostQuitMessage@4 ; сообщение WM_QUIT MOV EAX, 0 FINISH: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP _TEXT ENDS END START




Содержание  Назад  Вперед