.386 .model flat,stdcall ; определяем, что у нас сплошная("плоская") модель памяти, ;а stdcall говорит, что нужно уровнять стэк, после того как ф-ия будет прервана option casemap:none; включае эту ф-ию, чтобы различать в каких регистрах написана ф-ия ;############################################ ; подключили библиотеки include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib ;############################################# ; Объявили главную процедуру, которая будет состоять из 4 параметров WinMain proto :DWORD,:DWORD,:DWORD,:DWORD ; Инициализируем сегметнт данных .data ClassName db "SimpleWinClass",0 ; Имя нашего класса окна NameWindow db "Мое первое окно на ассемблере!!!",0 ; Имя окна .data? ; неинициализируемые данные hInstance HINSTANCE ? ; хендл программы CommandLine LPSTR ? ; обработка командной строки ; начало секции, где будет располагаться код .code start: invoke GetModuleHandle, NULL ; берем хэндл нашей программы mov hInstance,eax ; сохраним значение eax в переменную хэндл
invoke GetCommandLine ; вызвать командную строку mov CommandLine,eax ; обрабатываем командную строку ; вызываем основную функцию(4 параметра) invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT; вызываем нашу ; основную функцию invoke ExitProcess, eax ; выйти из программы
; Начнем основные действия с описания процедуры
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD LOCAL wc:WNDCLASSEX ; создаем 3 локальные переменные в стэке LOCAL msg:MSG LOCAL hwnd:HWND ; далее слует так: вызывается до точки член, а после его параметр mov wc.cbSize, SIZEOF WNDCLASSEX ; размер структуры mov wc.style, CS_HREDRAW or CS_VREDRAW ; стиль окна(у нас их 2) mov wc.lpfnWndProc, offset WndProc ; получим адрес процедуры окна, создаваемых из класса. mov wc.cbClsExtra, NULL ; кол-во резервиремых байт mov wc.cbWndExtra, NULL
push hInstance ; в стэк наш хэндл pop wc.hInstance ; извлекем из стэка переменную хэндл mov wc.hbrBackground, COLOR_WINDOW+1 ; цвет окна(белый) mov wc.lpszMenuName, NULL ; хэндл меню для окон, созданных из класса по умолчанию mov wc.lpszClassName, offset ClassName ; получаем имя класса окна invoke LoadIcon, NULL, IDI_APPLICATION ; вызываем API-функцию создания обычной(стандартной) ; иконки Windows mov wc.hIcon, eax ; хэндл иконки mov wc.hIconSm, eax ; хэндл для маленькой иконки invoke LoadCursor, NULL, IDC_ARROW ; вызываем API-функцию для создания курсора mov wc.hCursor, eax ; хэндл курсора invoke RegisterClassEx, addr wc ; регистрируем класс окна INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR NameWindow,\ ; вызываем API-функцию для создания окна(ф-ия имеет 12 параметров) WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\ hInst,NULL mov hwnd, eax ; значение eax в нашу переменную(хэндл), т.к. eax будет использоваться в дальнейшем invoke ShowWindow, hwnd,SW_SHOWNORMAL ; вызываем API-функцию , которая устанавливает состояние показа определяемого окна invoke UpdateWindow, hwnd ; вызываем API-функцию , которая модифицирует клиентскую область .WHILE TRUE ; используем цикл сообщений(чтобы обработать эти самые сообщения, иначе у нас не будет контакта с окном) invoke GetMessage, ADDR msg, NULL, 0, 0 ; вызываем API-ф-ию,которая последовательно проверяется, есть ли сообщения от Windows. .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg ; API-ф-ия, которая обрабатывает ввод с клавиатуры и генерирует новое сообщение invoke DispatchMessage, ADDR msg ; API-ф-ия, которая пересылает сообщение процедуре соответствующего окна .ENDW ; конец цикла mov eax, msg.wParam ; код выхода сохраняется в члене MSG структуры wParam ret ; выйдем из процедуры WinMain WinMain endp ; конец процедуры
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM ; процедура окна .if uMsg==WM_DESTROY ; посылаем сообщение функции, которая нужна чтобы уничтожить(закрыть) окно invoke PostQuitMessage, NULL ; это API функция , обрабатывающая сообщения, которыми ваша программа не нуждается .else ; иначе... invoke DefWindowProc, hWnd, uMsg, wParam, lParam ; вызываем DefWindowProc, которая ;обеспечивает обработку по умолчанию любого сообщения окна, которые приложение не обрабатывает ret ; пометим адрес возврата .endif ; конец условия xor eax, eax ; устанавливаем eax в 0 ret ; адрес возврата из WndProc WndProc endp ; окончателььно выходим из процедуры end start; конец всей программы составил MalCer