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



         

Пример простейшей программы с текстом - часть 2


WNDCLASS STRUC CLSSTYLE DD ? ; стиль окна CLSLPFNWNDPROC DD ? ; указатель на процедуру окна CLSCBCLSEXTRA DD ? ; информация о доп. байтах для данной структуры CLSCBWNDEXTRA DD ? ; информация о доп. байтах для окна CLSHINSTANCE DD ? ; дескриптор приложения CLSHICON DD ? ; идентификатор иконы окна CLSHCURSOR DD ? ; идентификатор курсора окна CLSHBRBACKGROUND DD ? ; идентификатор кисти окна MENNAME DD ? ; имя-идентификатор меню CLSNAME DD ? ; специфицирует имя класса окон WNDCLASS ENDS

PAINTSTR STRUC hdc DWORD 0 fErase DWORD 0 left DWORD 0 top DWORD 0 right DWORD 0 bottom DWORD 0 fRes DWORD 0 fIncUp DWORD 0 Reserv DB 32 dup (0) PAINTSTR ENDS

SIZET STRUC X1 DWORD ? Y1 DWORD ? SIZET ENDS

RECT STRUC L DWORD ? ; X - левого верхнего угла T DWORD ? ; Y - левого верхнего угла R DWORD ? ; X - правого нижнего угла B DWORD ? ; Y - правого нижнего угла RECT ENDS

; файл text2.asm .386P ; плоская модель .MODEL FLAT, stdcall ;------------------------------------------------------------ include text2.inc ; директивы компоновщику для подключения библиотек includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\gdi32.lib

; сегмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' NEWHWND DD 0 MSG MSGSTRUCT <?> WC WNDCLASS <?> PNT PAINTSTR <?> SZT SIZET <?> RCT RECT <?> HINST DD 0 TITLENAME DB 'Текст в окне',0 NAM DB 'CLASS32',0 XT DWORD ? YT DWORD ? TEXT DB 'Текст в окне зеленый',0 CONT DWORD ? _DATA ENDS

; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' START: ; получить дескриптор приложения PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX REG_CLASS: ; заполнить структуру окна стиль MOV [WC.CLSSTYLE],stylcl ; процедура обработки сообщений MOV [WC.CLSLPFNWNDPROC], OFFSET WNDPROC MOV [WC.CLSCBCLSEXTRA], 0 MOV [WC.CLSCBWNDEXTRA], 0 MOV EAX, [HINST] MOV [WC.CLSHINSTANCE], EAX ; ---------- иконка окна PUSH IDI_APPLICATION PUSH 0 CALL LoadIconA@8 MOV [WC.CLSHICON], EAX ;---------- курсор окна PUSH IDC_CROSS PUSH 0 CALL LoadCursorA@8 MOV [WC.CLSHCURSOR], EAX PUSH RGBW ; цвет кисти CALL CreateSolidBrush@4 ; создать кисть MOV [WC.CLSHBRBACKGROUND], EAX MOV DWORD PTR [WC.MENNAME],0 MOV DWORD PTR [WC.CLSNAME], OFFSET NAM PUSH OFFSET WC CALL RegisterClassA@4 ; создать окно зарегистрированного класса PUSH 0 PUSH [HINST] PUSH 0 PUSH 0 PUSH DY0 ; DY0 - высота окна PUSH DX0 ; DX0 - ширина окна PUSH 100 ; координата Y PUSH 100 ; координата X PUSH WS_OVERLAPPEDWINDOW PUSH OFFSET TITLENAME ; имя окна PUSH OFFSET NAM ; имя класса 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 ; перерисовать видимую часть окна ; петля обработки сообщений MSG_LOOP: PUSH 0 PUSH 0 PUSH 0 PUSH OFFSET MSG CALL GetMessageA@16 CMP AX, 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_PAINT JE WMPAINT JMP DEFWNDPROC WMPAINT: PUSH OFFSET PNT PUSH DWORD PTR [EBP+08H] CALL BeginPaint@8 MOV CONT,EAX ; сохранить контекст (дескриптор) ;---------------- цвет фона = цвет окна PUSH RGBW PUSH EAX CALL SetBkColor@8 ;---------------- цвет текста (красный) PUSH RGBT PUSH CONT CALL SetTextColor@8 ;- вычислить длину текста в пикселях текста PUSH OFFSET TEXT CALL LENSTR PUSH EBX ; сохраним длину строки PUSH OFFSET SZT PUSH EBX PUSH OFFSET TEXT PUSH CONT CALL GetTextExtentPoint32A@16 ;---------------- размер окна PUSH OFFSET RCT PUSH DWORD PTR [EBP+8] CALL GetWindowRect@8 ;---------------- здесь вычисления координат MOV EAX, RCT.R SUB EAX, RCT.L SUB EAX, SZT.X1 SHR EAX, 1 ; текст посередине MOV XT, EAX MOV EAX, RCT.B SUB EAX, RCT.T SHR EAX, 1 SUB EAX, 25 ; учтем заголовочную часть окна MOV YT,EAX ; ---------------- вывести текст ; длина строки уже в стеке PUSH OFFSET TEXT PUSH YT PUSH XT PUSH CONT CALL TextOutA@20 ;---------------- закрыть контекст PUSH OFFSET PNT PUSH DWORD PTR [EBP+08H] CALL EndPaint@8 MOV EAX, 0 JMP FINISH WMCREATE: 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 CALL PostQuitMessage@4 ; WM_QUIT MOV EAX, 0 FINISH: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP

; длина строки ; указатель на строку в - [EBP+08H] LENSTR PROC PUSH EBP MOV EBP,ESP PUSH ESI MOV ESI, DWORD PTR [EBP+8] XOR EBX, EBX LBL1: CMP BYTE PTR [ESI],0 JZ LBL2 INC EBX INC ESI JMP LBL1 LBL2: POP ESI POP EBP RET 4 LENSTR ENDP _TEXT ENDS END START




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