Hello, Win32 GUI(MASM) World!
Posted on 7月 6th, 2012 by cx20
Win32 GUI(MASM)
Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
以下は MASM における Win32 GUI アプリケーション の例となっている。
ソースコード
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.40219.01 TITLE hello.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES _DATA SEGMENT $SG79977 DB 'Hello, Win32 GUI(MASM) World!', 00H ORG $+2 $SG79995 DB 'helloWindow', 00H $SG79997 DB 'Hello, World!', 00H _DATA ENDS PUBLIC __$ArrayPad$ PUBLIC _WndProc@16 EXTRN __imp__DefWindowProcA@16:PROC EXTRN __imp__PostQuitMessage@4:PROC EXTRN __imp__EndPaint@8:PROC EXTRN __imp__TextOutA@20:PROC EXTRN __imp__lstrlenA@4:PROC EXTRN __imp__BeginPaint@8:PROC EXTRN ___security_cookie:DWORD EXTRN @__security_check_cookie@4:PROC ; Function compile flags: /Odtp _TEXT SEGMENT tv64 = -84 ; size = 4 _hdc$ = -80 ; size = 4 _lpszMessage$ = -76 ; size = 4 _ps$ = -72 ; size = 64 __$ArrayPad$ = -4 ; size = 4 _hWnd$ = 8 ; size = 4 _message$ = 12 ; size = 4 _wParam$ = 16 ; size = 4 _lParam$ = 20 ; size = 4 _WndProc@16 PROC ; File hello.c ; Line 5 push ebp mov ebp, esp sub esp, 84 ; 00000054H mov eax, DWORD PTR ___security_cookie xor eax, ebp mov DWORD PTR __$ArrayPad$[ebp], eax ; Line 8 mov DWORD PTR _lpszMessage$[ebp], OFFSET $SG79977 ; Line 10 mov eax, DWORD PTR _message$[ebp] mov DWORD PTR tv64[ebp], eax cmp DWORD PTR tv64[ebp], 2 je SHORT $LN2@WndProc cmp DWORD PTR tv64[ebp], 15 ; 0000000fH je SHORT $LN3@WndProc jmp SHORT $LN1@WndProc $LN3@WndProc: ; Line 13 lea ecx, DWORD PTR _ps$[ebp] push ecx mov edx, DWORD PTR _hWnd$[ebp] push edx call DWORD PTR __imp__BeginPaint@8 mov DWORD PTR _hdc$[ebp], eax ; Line 14 mov eax, DWORD PTR _lpszMessage$[ebp] push eax call DWORD PTR __imp__lstrlenA@4 push eax mov ecx, DWORD PTR _lpszMessage$[ebp] push ecx push 0 push 0 mov edx, DWORD PTR _hdc$[ebp] push edx call DWORD PTR __imp__TextOutA@20 ; Line 15 lea eax, DWORD PTR _ps$[ebp] push eax mov ecx, DWORD PTR _hWnd$[ebp] push ecx call DWORD PTR __imp__EndPaint@8 ; Line 16 jmp SHORT $LN4@WndProc $LN2@WndProc: ; Line 18 push 0 call DWORD PTR __imp__PostQuitMessage@4 ; Line 19 jmp SHORT $LN4@WndProc $LN1@WndProc: ; Line 21 mov edx, DWORD PTR _lParam$[ebp] push edx mov eax, DWORD PTR _wParam$[ebp] push eax mov ecx, DWORD PTR _message$[ebp] push ecx mov edx, DWORD PTR _hWnd$[ebp] push edx call DWORD PTR __imp__DefWindowProcA@16 jmp SHORT $LN6@WndProc $LN4@WndProc: ; Line 25 xor eax, eax $LN6@WndProc: ; Line 26 mov ecx, DWORD PTR __$ArrayPad$[ebp] xor ecx, ebp call @__security_check_cookie@4 mov esp, ebp pop ebp ret 16 ; 00000010H _WndProc@16 ENDP _TEXT ENDS PUBLIC _WinMain@16 EXTRN __imp__DispatchMessageA@4:PROC EXTRN __imp__TranslateMessage@4:PROC EXTRN __imp__GetMessageA@16:PROC EXTRN __imp__UpdateWindow@4:PROC EXTRN __imp__ShowWindow@8:PROC EXTRN __imp__CreateWindowExA@48:PROC EXTRN __imp__RegisterClassExA@4:PROC EXTRN __imp__LoadCursorA@8:PROC EXTRN __imp__LoadIconA@8:PROC ; Function compile flags: /Odtp _TEXT SEGMENT _lpszClassName$ = -88 ; size = 4 _msg$ = -84 ; size = 28 _wcex$ = -56 ; size = 48 _hWnd$ = -8 ; size = 4 _lpszWindowName$ = -4 ; size = 4 _hInstance$ = 8 ; size = 4 _hPrevInstance$ = 12 ; size = 4 _lpCmdLine$ = 16 ; size = 4 _nCmdShow$ = 20 ; size = 4 _WinMain@16 PROC ; Line 29 push ebp mov ebp, esp sub esp, 88 ; 00000058H ; Line 30 mov DWORD PTR _lpszClassName$[ebp], OFFSET $SG79995 ; Line 31 mov DWORD PTR _lpszWindowName$[ebp], OFFSET $SG79997 ; Line 36 mov DWORD PTR _wcex$[ebp], 48 ; 00000030H ; Line 37 mov DWORD PTR _wcex$[ebp+4], 3 ; Line 38 mov DWORD PTR _wcex$[ebp+8], OFFSET _WndProc@16 ; Line 39 mov DWORD PTR _wcex$[ebp+12], 0 ; Line 40 mov DWORD PTR _wcex$[ebp+16], 0 ; Line 41 mov eax, DWORD PTR _hInstance$[ebp] mov DWORD PTR _wcex$[ebp+20], eax ; Line 42 push 32512 ; 00007f00H mov ecx, DWORD PTR _hInstance$[ebp] push ecx call DWORD PTR __imp__LoadIconA@8 mov DWORD PTR _wcex$[ebp+24], eax ; Line 43 push 32512 ; 00007f00H push 0 call DWORD PTR __imp__LoadCursorA@8 mov DWORD PTR _wcex$[ebp+28], eax ; Line 44 mov DWORD PTR _wcex$[ebp+32], 6 ; Line 45 mov DWORD PTR _wcex$[ebp+36], 0 ; Line 46 mov edx, DWORD PTR _lpszClassName$[ebp] mov DWORD PTR _wcex$[ebp+40], edx ; Line 47 push 32512 ; 00007f00H mov eax, DWORD PTR _wcex$[ebp+20] push eax call DWORD PTR __imp__LoadIconA@8 mov DWORD PTR _wcex$[ebp+44], eax ; Line 49 lea ecx, DWORD PTR _wcex$[ebp] push ecx call DWORD PTR __imp__RegisterClassExA@4 ; Line 56 push 0 mov edx, DWORD PTR _hInstance$[ebp] push edx push 0 push 0 push 480 ; 000001e0H push 640 ; 00000280H push -2147483648 ; 80000000H push -2147483648 ; 80000000H push 13565952 ; 00cf0000H mov eax, DWORD PTR _lpszWindowName$[ebp] push eax mov ecx, DWORD PTR _lpszClassName$[ebp] push ecx push 0 call DWORD PTR __imp__CreateWindowExA@48 mov DWORD PTR _hWnd$[ebp], eax ; Line 58 push 10 ; 0000000aH mov edx, DWORD PTR _hWnd$[ebp] push edx call DWORD PTR __imp__ShowWindow@8 ; Line 59 mov eax, DWORD PTR _hWnd$[ebp] push eax call DWORD PTR __imp__UpdateWindow@4 $LN2@WinMain: ; Line 61 push 0 push 0 push 0 lea ecx, DWORD PTR _msg$[ebp] push ecx call DWORD PTR __imp__GetMessageA@16 test eax, eax je SHORT $LN1@WinMain ; Line 63 lea edx, DWORD PTR _msg$[ebp] push edx call DWORD PTR __imp__TranslateMessage@4 ; Line 64 lea eax, DWORD PTR _msg$[ebp] push eax call DWORD PTR __imp__DispatchMessageA@4 ; Line 65 jmp SHORT $LN2@WinMain $LN1@WinMain: ; Line 67 mov eax, DWORD PTR _msg$[ebp+8] ; Line 68 mov esp, ebp pop ebp ret 16 ; 00000010H _WinMain@16 ENDP _TEXT ENDS END |
上記コードは以下のC言語のソースを VC++ でアセンブリコード出力(cl /FA hello.c)したものに相当する。
#include <windows.h> #include <tchar.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; LPCTSTR lpszMessage = _T("Hello, Win32 GUI(MASM) World!"); switch (message) { case WM_PAINT: hdc = BeginPaint( hWnd, &ps ); TextOut( hdc, 0, 0, lpszMessage, lstrlen(lpszMessage) ); EndPaint( hWnd, &ps ); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); break; } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { LPCTSTR lpszClassName = _T("helloWindow"); LPCTSTR lpszWindowName = _T("Hello, World!"); WNDCLASSEX wcex; HWND hWnd; MSG msg; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = lpszClassName; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); RegisterClassEx(&wcex); hWnd = CreateWindow( lpszClassName, lpszWindowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL ); ShowWindow(hWnd, SW_SHOWDEFAULT); UpdateWindow(hWnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } |
コンパイル方法
C:¥> ml hello.asm /link user32.lib gdi32.lib /SUBSYSTEM:WINDOWS |
実行結果
+------------------------------------------+ |Hello, World! [_][~][X]| +------------------------------------------+ |Hello, Win32 GUI(MASM) World! | | | | | | | | | | | | | | | | | | | +------------------------------------------+ |
Tags: Win32 GUI