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:

Categories: assembler, MASM, Win32 API, Win32 GUI

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

WP-SpamFree by Pole Position Marketing