Archive for 7月 27th, 2012
-
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! | | | | | | | | | | | | | | | | | | | +------------------------------------------+