Archive for the ‘MASM’ Category

  1. Hello, DirectX(MASM) World!

    Posted on 7月 27th, 2012 by cx20

    Win32 DirectX(MASM)

    DirectX はマイクロソフトが Wnidows 用に開発したマルチメディア処理用 API である。
    以下は MSAM における DirectX アプリケーション の例となっている。

    ソースコード

    ; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.762 
     
            TITLE   hello.c
            .686P
            .XMM
            include listing.inc
            .model  flat
     
    INCLUDELIB LIBCMT
    INCLUDELIB OLDNAMES
     
    PUBLIC  _g_pD3D
    PUBLIC  _g_pd3dDevice
    PUBLIC  _g_pd3dFont
    PUBLIC  _g_rect
    _BSS    SEGMENT
    _g_pD3D DD      01H DUP (?)
    _g_pd3dDevice DD 01H DUP (?)
    _g_pd3dFont DD  01H DUP (?)
    _g_rect DB      010H DUP (?)
    _BSS    ENDS
    _DATA   SEGMENT
    $SG94060 DB     082H, 'l', 082H, 'r ', 083H, 'S', 083H, 'V', 083H, 'b', 083H
            DB      'N', 00H
            ORG $+2
    $SG94064 DB     'Hello, DirectX(MASM) World!', 00H
    $SG94084 DB     'Hello, DirectX(MASM) World!', 00H
    $SG94116 DB     'helloWindow', 00H
    $SG94118 DB     'Hello, World!', 00H
    _DATA   ENDS
    PUBLIC  _InitD3D
    EXTRN   _Direct3DCreate9@4:PROC
    ; Function compile flags: /Odtp
    _TEXT   SEGMENT
    _d3dpp$ = -60                                           ; size = 56
    _hr$ = -4                                               ; size = 4
    _hWnd$ = 8                                              ; size = 4
    _InitD3D PROC
    ; File hello.c
    ; Line 17
            push    ebp
            mov     ebp, esp
            sub     esp, 60                                 ; 0000003cH
    ; Line 20
            push    32                                      ; 00000020H
            call    _Direct3DCreate9@4
            mov     DWORD PTR _g_pD3D, eax
    ; Line 21
            cmp     DWORD PTR _g_pD3D, 0
            jne     SHORT $LN2@InitD3D
    ; Line 23
            mov     eax, -2147467259                        ; 80004005H
            jmp     $LN3@InitD3D
    $LN2@InitD3D:
    ; Line 26
            mov     DWORD PTR _d3dpp$[ebp], 0
    ; Line 27
            mov     DWORD PTR _d3dpp$[ebp+4], 0
    ; Line 28
            mov     DWORD PTR _d3dpp$[ebp+8], 0
    ; Line 29
            mov     DWORD PTR _d3dpp$[ebp+12], 0
    ; Line 30
            mov     DWORD PTR _d3dpp$[ebp+16], 0
    ; Line 31
            mov     DWORD PTR _d3dpp$[ebp+20], 0
    ; Line 32
            mov     DWORD PTR _d3dpp$[ebp+24], 1
    ; Line 33
            mov     DWORD PTR _d3dpp$[ebp+28], 0
    ; Line 34
            mov     DWORD PTR _d3dpp$[ebp+32], 1
    ; Line 35
            mov     DWORD PTR _d3dpp$[ebp+36], 0
    ; Line 36
            mov     DWORD PTR _d3dpp$[ebp+40], 0
    ; Line 37
            mov     DWORD PTR _d3dpp$[ebp+44], 0
    ; Line 38
            mov     DWORD PTR _d3dpp$[ebp+48], 0
    ; Line 39
            mov     DWORD PTR _d3dpp$[ebp+52], 0
    ; Line 49
            push    OFFSET _g_pd3dDevice
            lea     eax, DWORD PTR _d3dpp$[ebp]
            push    eax
            push    32                                      ; 00000020H
            mov     ecx, DWORD PTR _hWnd$[ebp]
            push    ecx
            push    1
            push    0
            mov     edx, DWORD PTR _g_pD3D
            push    edx
            mov     eax, DWORD PTR _g_pD3D
            mov     ecx, DWORD PTR [eax]
            mov     edx, DWORD PTR [ecx+64]
            call    edx
            mov     DWORD PTR _hr$[ebp], eax
    ; Line 51
            cmp     DWORD PTR _hr$[ebp], 0
            jge     SHORT $LN1@InitD3D
    ; Line 53
            mov     eax, -2147467259                        ; 80004005H
            jmp     SHORT $LN3@InitD3D
    $LN1@InitD3D:
    ; Line 56
            xor     eax, eax
    $LN3@InitD3D:
    ; Line 57
            mov     esp, ebp
            pop     ebp
            ret     0
    _InitD3D ENDP
    _TEXT   ENDS
    PUBLIC  _Cleanup
    PUBLIC  __$ArrayPad$
    PUBLIC  _InitFont
    EXTRN   _D3DXCreateFontIndirectA@12:PROC
    EXTRN   __imp__lstrcpyA@8:PROC
    EXTRN   ___security_cookie:DWORD
    EXTRN   @__security_check_cookie@4:PROC
    ; Function compile flags: /Odtp
    _TEXT   SEGMENT
    _hr$ = -64                                              ; size = 4
    _lf$ = -60                                              ; size = 56
    __$ArrayPad$ = -4                                       ; size = 4
    _InitFont PROC
    ; Line 60
            push    ebp
            mov     ebp, esp
            sub     esp, 64                                 ; 00000040H
            mov     eax, DWORD PTR ___security_cookie
            xor     eax, ebp
            mov     DWORD PTR __$ArrayPad$[ebp], eax
    ; Line 64
            mov     DWORD PTR _lf$[ebp], 16                 ; 00000010H
    ; Line 65
            mov     DWORD PTR _lf$[ebp+4], 0
    ; Line 66
            mov     DWORD PTR _lf$[ebp+8], 0
    ; Line 67
            mov     DWORD PTR _lf$[ebp+12], 1
    ; Line 68
            mov     DWORD PTR _lf$[ebp+16], 0
    ; Line 69
            mov     BYTE PTR _lf$[ebp+20], 128              ; 00000080H
    ; Line 70
            mov     BYTE PTR _lf$[ebp+21], 7
    ; Line 71
            mov     BYTE PTR _lf$[ebp+22], 2
    ; Line 72
            mov     BYTE PTR _lf$[ebp+23], 49               ; 00000031H
    ; Line 73
            push    OFFSET $SG94060
            lea     eax, DWORD PTR _lf$[ebp+24]
            push    eax
            call    DWORD PTR __imp__lstrcpyA@8
    ; Line 75
            push    OFFSET _g_pd3dFont
            lea     ecx, DWORD PTR _lf$[ebp]
            push    ecx
            mov     edx, DWORD PTR _g_pd3dDevice
            push    edx
            call    _D3DXCreateFontIndirectA@12
            mov     DWORD PTR _hr$[ebp], eax
    ; Line 76
            cmp     DWORD PTR _hr$[ebp], 0
            jge     SHORT $LN2@InitFont
    ; Line 78
            call    _Cleanup
    ; Line 79
            mov     eax, DWORD PTR _hr$[ebp]
            jmp     SHORT $LN3@InitFont
    $LN2@InitFont:
    ; Line 90
            push    -1
            push    1056                                    ; 00000420H
            push    OFFSET _g_rect
            push    -1
            push    OFFSET $SG94064
            push    0
            mov     eax, DWORD PTR _g_pd3dFont
            push    eax
            mov     ecx, DWORD PTR _g_pd3dFont
            mov     edx, DWORD PTR [ecx]
            mov     eax, DWORD PTR [edx+56]
            call    eax
            mov     DWORD PTR _hr$[ebp], eax
    ; Line 92
            cmp     DWORD PTR _hr$[ebp], 0
            jge     SHORT $LN1@InitFont
    ; Line 94
            call    _Cleanup
    ; Line 95
            mov     eax, DWORD PTR _hr$[ebp]
            jmp     SHORT $LN3@InitFont
    $LN1@InitFont:
    ; Line 98
            mov     eax, DWORD PTR _hr$[ebp]
    $LN3@InitFont:
    ; Line 99
            mov     ecx, DWORD PTR __$ArrayPad$[ebp]
            xor     ecx, ebp
            call    @__security_check_cookie@4
            mov     esp, ebp
            pop     ebp
            ret     0
    _InitFont ENDP
    ; Function compile flags: /Odtp
    _Cleanup PROC
    ; Line 102
            push    ebp
            mov     ebp, esp
    ; Line 103
            cmp     DWORD PTR _g_pd3dFont, 0
            je      SHORT $LN3@Cleanup
    ; Line 105
            mov     eax, DWORD PTR _g_pd3dFont
            push    eax
            mov     ecx, DWORD PTR _g_pd3dFont
            mov     edx, DWORD PTR [ecx]
            mov     eax, DWORD PTR [edx+8]
            call    eax
    $LN3@Cleanup:
    ; Line 108
            cmp     DWORD PTR _g_pd3dDevice, 0
            je      SHORT $LN2@Cleanup
    ; Line 110
            mov     ecx, DWORD PTR _g_pd3dDevice
            push    ecx
            mov     edx, DWORD PTR _g_pd3dDevice
            mov     eax, DWORD PTR [edx]
            mov     ecx, DWORD PTR [eax+8]
            call    ecx
    $LN2@Cleanup:
    ; Line 113
            cmp     DWORD PTR _g_pD3D, 0
            je      SHORT $LN4@Cleanup
    ; Line 115
            mov     edx, DWORD PTR _g_pD3D
            push    edx
            mov     eax, DWORD PTR _g_pD3D
            mov     ecx, DWORD PTR [eax]
            mov     edx, DWORD PTR [ecx+8]
            call    edx
    $LN4@Cleanup:
    ; Line 117
            pop     ebp
            ret     0
    _Cleanup ENDP
    _TEXT   ENDS
    PUBLIC  __real@3f800000
    PUBLIC  _Render
    EXTRN   __fltused:DWORD
    ;       COMDAT __real@3f800000
    CONST   SEGMENT
    __real@3f800000 DD 03f800000r                   ; 1
    ; Function compile flags: /Odtp
    CONST   ENDS
    _TEXT   SEGMENT
    _Render PROC
    ; Line 120
            push    ebp
            mov     ebp, esp
    ; Line 121
            cmp     DWORD PTR _g_pd3dDevice, 0
            jne     SHORT $LN3@Render
    ; Line 123
            jmp     $LN4@Render
    $LN3@Render:
    ; Line 126
            cmp     DWORD PTR _g_pd3dFont, 0
            jne     SHORT $LN2@Render
    ; Line 128
            jmp     $LN4@Render
    $LN2@Render:
    ; Line 139
            push    0
            push    ecx
            fld1
            fstp    DWORD PTR [esp]
            push    -16776961                               ; ff0000ffH
            push    1
            push    0
            push    0
            mov     eax, DWORD PTR _g_pd3dDevice
            push    eax
            mov     ecx, DWORD PTR _g_pd3dDevice
            mov     edx, DWORD PTR [ecx]
            mov     eax, DWORD PTR [edx+172]
            call    eax
    ; Line 141
            mov     ecx, DWORD PTR _g_pd3dDevice
            push    ecx
            mov     edx, DWORD PTR _g_pd3dDevice
            mov     eax, DWORD PTR [edx]
            mov     ecx, DWORD PTR [eax+164]
            call    ecx
            test    eax, eax
            jl      SHORT $LN1@Render
    ; Line 151
            push    -1
            push    32                                      ; 00000020H
            push    OFFSET _g_rect
            push    -1
            push    OFFSET $SG94084
            push    0
            mov     edx, DWORD PTR _g_pd3dFont
            push    edx
            mov     eax, DWORD PTR _g_pd3dFont
            mov     ecx, DWORD PTR [eax]
            mov     edx, DWORD PTR [ecx+56]
            call    edx
    ; Line 153
            mov     eax, DWORD PTR _g_pd3dDevice
            push    eax
            mov     ecx, DWORD PTR _g_pd3dDevice
            mov     edx, DWORD PTR [ecx]
            mov     eax, DWORD PTR [edx+168]
            call    eax
    $LN1@Render:
    ; Line 156
            push    0
            push    0
            push    0
            push    0
            mov     ecx, DWORD PTR _g_pd3dDevice
            push    ecx
            mov     edx, DWORD PTR _g_pd3dDevice
            mov     eax, DWORD PTR [edx]
            mov     ecx, DWORD PTR [eax+68]
            call    ecx
    $LN4@Render:
    ; Line 157
            pop     ebp
            ret     0
    _Render ENDP
    _TEXT   ENDS
    PUBLIC  _WndProc@16
    EXTRN   __imp__DefWindowProcA@16:PROC
    EXTRN   __imp__ValidateRect@8:PROC
    EXTRN   __imp__PostQuitMessage@4:PROC
    ; Function compile flags: /Odtp
    _TEXT   SEGMENT
    tv64 = -4                                               ; size = 4
    _hWnd$ = 8                                              ; size = 4
    _message$ = 12                                          ; size = 4
    _wParam$ = 16                                           ; size = 4
    _lParam$ = 20                                           ; size = 4
    _WndProc@16 PROC
    ; Line 160
            push    ebp
            mov     ebp, esp
            push    ecx
    ; Line 161
            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 $LN1@WndProc
            jmp     SHORT $LN3@WndProc
    $LN2@WndProc:
    ; Line 164
            call    _Cleanup
    ; Line 165
            push    0
            call    DWORD PTR __imp__PostQuitMessage@4
    ; Line 166
            xor     eax, eax
            jmp     SHORT $LN5@WndProc
    $LN1@WndProc:
    ; Line 169
            call    _Render
    ; Line 170
            push    0
            mov     ecx, DWORD PTR _hWnd$[ebp]
            push    ecx
            call    DWORD PTR __imp__ValidateRect@8
    ; Line 171
            xor     eax, eax
            jmp     SHORT $LN5@WndProc
    $LN3@WndProc:
    ; Line 174
            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
    $LN5@WndProc:
    ; Line 175
            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 178
            push    ebp
            mov     ebp, esp
            sub     esp, 88                                 ; 00000058H
    ; Line 179
            mov     DWORD PTR _lpszClassName$[ebp], OFFSET $SG94116
    ; Line 180
            mov     DWORD PTR _lpszWindowName$[ebp], OFFSET $SG94118
    ; Line 185
            mov     DWORD PTR _wcex$[ebp], 48               ; 00000030H
    ; Line 186
            mov     DWORD PTR _wcex$[ebp+4], 3
    ; Line 187
            mov     DWORD PTR _wcex$[ebp+8], OFFSET _WndProc@16
    ; Line 188
            mov     DWORD PTR _wcex$[ebp+12], 0
    ; Line 189
            mov     DWORD PTR _wcex$[ebp+16], 0
    ; Line 190
            mov     eax, DWORD PTR _hInstance$[ebp]
            mov     DWORD PTR _wcex$[ebp+20], eax
    ; Line 191
            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 192
            push    32512                                   ; 00007f00H
            push    0
            call    DWORD PTR __imp__LoadCursorA@8
            mov     DWORD PTR _wcex$[ebp+28], eax
    ; Line 193
            mov     DWORD PTR _wcex$[ebp+32], 6
    ; Line 194
            mov     DWORD PTR _wcex$[ebp+36], 0
    ; Line 195
            mov     edx, DWORD PTR _lpszClassName$[ebp]
            mov     DWORD PTR _wcex$[ebp+40], edx
    ; Line 196
            push    32512                                   ; 00007f00H
            mov     eax, DWORD PTR _hInstance$[ebp]
            push    eax
            call    DWORD PTR __imp__LoadIconA@8
            mov     DWORD PTR _wcex$[ebp+44], eax
    ; Line 198
            lea     ecx, DWORD PTR _wcex$[ebp]
            push    ecx
            call    DWORD PTR __imp__RegisterClassExA@4
    ; Line 205
            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 207
            mov     edx, DWORD PTR _hWnd$[ebp]
            push    edx
            call    _InitD3D
            add     esp, 4
    ; Line 208
            call    _InitFont
    ; Line 210
            push    10                                      ; 0000000aH
            mov     eax, DWORD PTR _hWnd$[ebp]
            push    eax
            call    DWORD PTR __imp__ShowWindow@8
    ; Line 211
            mov     ecx, DWORD PTR _hWnd$[ebp]
            push    ecx
            call    DWORD PTR __imp__UpdateWindow@4
    $LN2@WinMain:
    ; Line 213
            push    0
            push    0
            push    0
            lea     edx, DWORD PTR _msg$[ebp]
            push    edx
            call    DWORD PTR __imp__GetMessageA@16
            test    eax, eax
            je      SHORT $LN1@WinMain
    ; Line 215
            lea     eax, DWORD PTR _msg$[ebp]
            push    eax
            call    DWORD PTR __imp__TranslateMessage@4
    ; Line 216
            lea     ecx, DWORD PTR _msg$[ebp]
            push    ecx
            call    DWORD PTR __imp__DispatchMessageA@4
    ; Line 217
            jmp     SHORT $LN2@WinMain
    $LN1@WinMain:
    ; Line 219
            xor     eax, eax
    ; Line 220
            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>
    #include <d3d9.h>
    #include <d3dx9.h>
     
    LPDIRECT3D9         g_pD3D       = NULL;
    LPDIRECT3DDEVICE9   g_pd3dDevice = NULL;
    LPD3DXFONT          g_pd3dFont   = NULL;
    RECT                g_rect       = { 0, 0, 0, 0 };
     
    HRESULT InitD3D( HWND hWnd );
    HRESULT InitFont();
    VOID Cleanup();
    VOID Render();
     
    HRESULT InitD3D( HWND hWnd )
    {
        HRESULT hr;
        D3DPRESENT_PARAMETERS d3dpp;
        g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
        if( g_pD3D == NULL )
        {
            return E_FAIL;
        }
     
        d3dpp.BackBufferWidth             = 0;
        d3dpp.BackBufferHeight            = 0;
        d3dpp.BackBufferFormat            = D3DFMT_UNKNOWN;
        d3dpp.BackBufferCount             = 0;
        d3dpp.MultiSampleType             = D3DMULTISAMPLE_NONE;
        d3dpp.MultiSampleQuality          = 0;
        d3dpp.SwapEffect                  = D3DSWAPEFFECT_DISCARD;
        d3dpp.hDeviceWindow               = NULL;
        d3dpp.Windowed                    = TRUE;
        d3dpp.EnableAutoDepthStencil      = 0;
        d3dpp.AutoDepthStencilFormat      = D3DFMT_UNKNOWN;
        d3dpp.Flags                       = 0;
        d3dpp.FullScreen_RefreshRateInHz  = 0;
        d3dpp.PresentationInterval        = 0;
     
        hr = g_pD3D->lpVtbl->CreateDevice(
            g_pD3D,
            D3DADAPTER_DEFAULT,
            D3DDEVTYPE_HAL,
            hWnd,
            D3DCREATE_SOFTWARE_VERTEXPROCESSING,
            &d3dpp,
            &g_pd3dDevice
        );
     
        if( FAILED( hr ) )
        {
            return E_FAIL;
        }
     
        return S_OK;
    }
     
    HRESULT InitFont()
    {
        HRESULT hr;
     
        D3DXFONT_DESC lf;
        lf.Height          = 16;
        lf.Width           = 0;
        lf.Weight          = 0;
        lf.MipLevels       = 1;
        lf.Italic          = 0;
        lf.CharSet         = SHIFTJIS_CHARSET;
        lf.OutputPrecision = OUT_TT_ONLY_PRECIS;
        lf.Quality         = PROOF_QUALITY;
        lf.PitchAndFamily  = FIXED_PITCH | FF_MODERN;
        lstrcpy( lf.FaceName, _T("MS ゴシック") );
     
        hr = D3DXCreateFontIndirect( g_pd3dDevice, &lf, &g_pd3dFont );
        if ( FAILED( hr ) )
        {
            Cleanup();
            return hr;
        }
     
        hr = g_pd3dFont->lpVtbl->DrawText(
            g_pd3dFont,
            NULL, 
            _T("Hello, DirectX(MASM) World!"),
            -1,
            &g_rect,
            DT_CALCRECT | DT_LEFT | DT_SINGLELINE,
            0xffffffff
        );
     
        if ( FAILED( hr ) )
        {
            Cleanup();
            return hr;
        }
     
        return hr;
    }
     
    VOID Cleanup()
    {
        if ( g_pd3dFont != NULL )
        {
            g_pd3dFont->lpVtbl->Release( g_pd3dFont );
        }
     
        if( g_pd3dDevice != NULL )
        {
            g_pd3dDevice->lpVtbl->Release( g_pd3dDevice );
        }
     
        if( g_pD3D != NULL )
        {
            g_pD3D->lpVtbl->Release( g_pD3D );
        }
    }
     
    VOID Render()
    {
        if( g_pd3dDevice == NULL )
        {
            return;
        }
     
        if ( g_pd3dFont == NULL )
        {
            return;
        }
     
        g_pd3dDevice->lpVtbl->Clear(
            g_pd3dDevice,
            0, 
            NULL,
            D3DCLEAR_TARGET,
            D3DCOLOR_XRGB( 0, 0, 255 ),
            1.0f,
            0
        );
     
        if( SUCCEEDED( g_pd3dDevice->lpVtbl->BeginScene( g_pd3dDevice ) ) )
        {
            g_pd3dFont->lpVtbl->DrawText( 
                g_pd3dFont,
                NULL,
                _T("Hello, DirectX(MASM) World!"),
                -1,
                &g_rect,
                DT_LEFT | DT_SINGLELINE,
                0xffffffff
            );
     
            g_pd3dDevice->lpVtbl->EndScene( g_pd3dDevice );
        }
     
        g_pd3dDevice->lpVtbl->Present( g_pd3dDevice, NULL, NULL, NULL, NULL );
    }
     
    LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    {
        switch( message )
        {
            case WM_DESTROY:
                Cleanup();
                PostQuitMessage( 0 );
                return 0;
     
            case WM_PAINT:
                Render();
                ValidateRect( hWnd, NULL );
                return 0;
        }
     
        return DefWindowProc( hWnd, message, wParam, lParam );
    }
     
    int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
    {
        LPCTSTR lpszClassName = _T("helloWindow");
        LPCTSTR lpszWindowName = _T("Hello, World!");
        MSG msg;
        HWND hWnd;
     
        WNDCLASSEX wcex;
        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(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
     
        RegisterClassEx(&wcex);
        hWnd = CreateWindow(
            lpszClassName,
            lpszWindowName,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
            NULL, NULL, hInstance, NULL
        );
     
        InitD3D( hWnd );
        InitFont();
     
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );
     
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
     
        return 0;
    }

    コンパイル方法

    C:¥> SET INCLUDE=%DXSDK_DIR%INCLUDE;%INCLUDE%
    C:¥> SET LIB=%DXSDK_DIR%Libx86;%LIB%
    C:¥> ml hello.asm ^
             /link ^
             user32.lib ^
             dxguid.lib ^
             d3d9.lib ^
             d3dx9.lib ^
             /SUBSYSTEM:WINDOWS

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, DirectX(MASM) World!               |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  2. 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!             |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+
  3. Hello, COM(MASM) World!

    Posted on 5月 12th, 2012 by cx20

    COM(MASM)

    COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
    COM を用いて開発された部品であれば言語を問わず利用することができる。
    以下は MASM による COM クライアントの例となっている。

    ソースコード

    ; 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
    $SG113507 DB	'H', 00H, 'e', 00H, 'l', 00H, 'l', 00H, 'o', 00H, ',', 00H
    	DB	' ', 00H, 'C', 00H, 'O', 00H, 'M', 00H, '(', 00H, 'M', 00H, 'A'
    	DB	00H, 'S', 00H, 'M', 00H, ')', 00H, ' ', 00H, 'W', 00H, 'o', 00H
    	DB	'r', 00H, 'l', 00H, 'd', 00H, '!', 00H, 00H, 00H
    _DATA	ENDS
    PUBLIC	_main
    EXTRN	__imp__CoUninitialize@0:PROC
    EXTRN	__imp__CoCreateInstance@20:PROC
    EXTRN	_CLSID_Shell:BYTE
    EXTRN	_IID_IShellDispatch:BYTE
    EXTRN	__imp__CoInitialize@4:PROC
    ; Function compile flags: /Odtp
    _TEXT	SEGMENT
    _pFolder$ = -36						; size = 4
    _vRootFolder$ = -32					; size = 16
    _folder$ = -12						; size = 4
    _pShell$ = -4						; size = 4
    _argc$ = 8						; size = 4
    _argv$ = 12						; size = 4
    _main	PROC
    ; File hello.c
    ; Line 4
            push    ebp
            mov     ebp, esp
            sub     esp, 36                                 ; 00000024H
    ; Line 11
            push    0
            call    DWORD PTR __imp__CoInitialize@4
    ; Line 13
            lea     eax, DWORD PTR _pShell$[ebp]
            push    eax
            push    OFFSET _IID_IShellDispatch
            push    1
            push    0
            push    OFFSET _CLSID_Shell
            call    DWORD PTR __imp__CoCreateInstance@20
    ; Line 15
            mov     ecx, 3
            mov     WORD PTR _vRootFolder$[ebp], cx
    ; Line 16
            mov     DWORD PTR _vRootFolder$[ebp+8], 36      ; 00000024H
    ; Line 17
            lea     edx, DWORD PTR _folder$[ebp]
            mov     DWORD PTR _pFolder$[ebp], edx
    ; Line 19
            lea     eax, DWORD PTR _pFolder$[ebp]
            push    eax
            sub     esp, 16                                 ; 00000010H
            mov     ecx, esp
            mov     edx, DWORD PTR _vRootFolder$[ebp]
            mov     DWORD PTR [ecx], edx
            mov     eax, DWORD PTR _vRootFolder$[ebp+4]
            mov     DWORD PTR [ecx+4], eax
            mov     edx, DWORD PTR _vRootFolder$[ebp+8]
            mov     DWORD PTR [ecx+8], edx
            mov     eax, DWORD PTR _vRootFolder$[ebp+12]
            mov     DWORD PTR [ecx+12], eax
            push    0
            push    OFFSET $SG113507
            push    0
            mov     ecx, DWORD PTR _pShell$[ebp]
            push    ecx
            mov     edx, DWORD PTR _pShell$[ebp]
            mov     eax, DWORD PTR [edx]
            mov     ecx, DWORD PTR [eax+40]
            call    ecx
    ; Line 20
            cmp     DWORD PTR _pFolder$[ebp], 0
            je      SHORT $LN1@main
    ; Line 22
            mov     edx, DWORD PTR _pFolder$[ebp]
            push    edx
            mov     eax, DWORD PTR _pFolder$[ebp]
            mov     ecx, DWORD PTR [eax]
            mov     edx, DWORD PTR [ecx+8]
            call    edx
    $LN1@main:
    ; Line 24
            mov     eax, DWORD PTR _pShell$[ebp]
            push    eax
            mov     ecx, DWORD PTR _pShell$[ebp]
            mov     edx, DWORD PTR [ecx]
            mov     eax, DWORD PTR [edx+8]
            call    eax
    ; Line 26
            call    DWORD PTR __imp__CoUninitialize@0
    ; Line 28
            xor     eax, eax
    ; Line 29
            mov     esp, ebp
            pop     ebp
            ret     0
    _main   ENDP
    _TEXT   ENDS
    END

    上記コードは以下のC言語のソースを VC++ でアセンブリコード出力(cl /FA hello.c)したものに相当する。

    #include <shlobj.h>
     
    int main( int argc, char* argv[] )
    {
        HRESULT hResult;
        IShellDispatch* pShell;
        VARIANT vRootFolder;
        Folder* pFolder;
     
        CoInitialize( NULL );
     
        CoCreateInstance( &CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void**)&pShell );
     
        VariantInit( &vRootFolder );
        vRootFolder.vt = VT_I4;
        vRootFolder.lVal = ssfWINDOWS;
     
        pShell->lpVtbl->BrowseForFolder( (void*)pShell, 0, L"Hello, COM(MASM) World!", 0, vRootFolder, &pFolder );
        VariantClear( &vRootFolder );
        if ( pFolder != NULL )
        {
            pFolder->lpVtbl->Release( (void*)pFolder );
        }
        pShell->lpVtbl->Release( (void*)pShell );
     
        CoUninitialize();
     
        return 0;
    }

    コンパイル&リンク方法

    C:¥> ml -c hello.asm
    C:¥> midl shldisp.idl
    C:¥> cl shldisp_i.c
    C:¥> link hello.obj shldisp_i.obj ole32.lib oleaut32.lib

    実行結果

    +----------------------------------------+
    |Browse For Folder                    [X]|
    +----------------------------------------+
    | Hello, COM(MASM) Wolrd!                |
    |                                        |
    | +------------------------------------+ |
    | |[Windows]                           | |
    | | +[addins]                          | |
    | | +[AppCompat]                       | |
    | | +[AppPatch]                        | |
    | | +[assembly]                        | |
    | |     :                              | |
    | |     :                              | |
    | |     :                              | |
    | +------------------------------------+ |
    | [Make New Folder]    [  OK  ] [Cancel] |
    +----------------------------------------+
  4. Hello, Win32 API(MASM) World!

    Posted on 4月 17th, 2012 by cx20

    Win32 API(MASM)

    Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
    以下は MASM からの呼出し例である。

    ソースコード(MASM)

    ; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.762 
     
            TITLE   hello.c
            .686P
            .XMM
            include listing.inc
            .model  flat
     
    INCLUDELIB LIBCMT
    INCLUDELIB OLDNAMES
     
    _DATA   SEGMENT
    $SG77810 DB     'Hello, World!', 00H
            ORG $+2
    $SG77811 DB     'Hello, Win32 API(MASM) World!', 00H
    _DATA   ENDS
    PUBLIC  _main
    EXTRN   __imp__MessageBoxA@16:PROC
    ; Function compile flags: /Odtp
    _TEXT   SEGMENT
    _argc$ = 8                                              ; size = 4
    _argv$ = 12                                             ; size = 4
    _main   PROC
    ; File hello.c
    ; Line 4
            push    ebp
            mov     ebp, esp
    ; Line 5
            push    0
            push    OFFSET $SG77810
            push    OFFSET $SG77811
            push    0
            call    DWORD PTR __imp__MessageBoxA@16
    ; Line 6
            xor     eax, eax
    ; Line 7
            pop     ebp
            ret     0
    _main   ENDP
    _TEXT   ENDS
    END

    上記コードは、下記の C のソースを「cl hello.c /FA」にてアセンブラ出力したものである。

    ソースコード(C言語)

    #include <windows.h>
     
    int main( int argc, char* argv[] )
    {
        MessageBoxA( NULL, "Hello, Win32 API(MASM) World!", "Hello, World!", MB_OK );
        return 0;
    }

    コンパイル方法(Visual C++)

    C:¥> ml hello.asm
    C:¥> link hello.obj user32.lib

    実行結果

    ---------------------------
    Hello, World!
    ---------------------------
    Hello, Win32 API(MASM) World!
    ---------------------------
    OK   
    ---------------------------
  5. Hello, MASM World!

    Posted on 1月 4th, 2012 by cx20

    MASM

    MASM はマイクロソフト社製のアセンブリ言語である。正式名称は Microsoft Macro Assembler。Visual C++ に付属している。

    ソースコード(32bit版)

    .MODEL flat
    EXTRN   _printf:PROC
     
    _DATA   SEGMENT
    msg     DB      'Hello, MASM World!', 0aH, 00H
    _DATA   ENDS
     
    _TEXT   SEGMENT
    _main   PROC
            push    OFFSET msg
            call    _printf
            add     esp, 4
            xor     eax, eax
            ret     0
    _main   ENDP
    _TEXT   ENDS
    END

    ソースコード(64bit版)

    EXTRN   printf:PROC
     
    _DATA   SEGMENT
    msg     DB      'Hello, MASM World!', 0aH, 00H
    _DATA   ENDS
     
    _TEXT   SEGMENT
    main    PROC
            sub     rsp, 40
            lea     rcx, OFFSET msg
            call    printf
            xor     rax, rax
            add     rsp, 40
            ret     0
    main    ENDP
    _TEXT   ENDS
    END

    上記コードは以下のC言語のソースを VC++ でアセンブリコード出力(cl /FA hello.c)したものに相当する。

    #include <stdio.h>
     
    int main( int argc, char* argv[] )
    {
        printf( "Hello, MASM World!n" );
        return 0;
    }

    コンパイル&リンク方法(MASM 32bit版)

    C:¥> ml -c hello.asm
    C:¥> link hello.obj libcmt.lib

    コンパイル&リンク方法(MASM 64bit版)

    C:¥> ml64 -c hello64.asm
    C:¥> link hello64.obj libcmt.lib

    実行結果

    Hello, MASM World!