Archive for 7月 6th, 2012

  1. 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!             |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+