Archive for the ‘assembler’ Category
-
Hello, COM(GAS) World!
Posted on 3月 18th, 2013 by cx20
COM(GAS)
COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は GAS による COM クライアントの例となっている。ソースコード
.file "hello.c" .def ___main; .scl 2; .type 32; .endef .section .rdata,"dr" .align 4 LC0: .ascii "B
上記コードは以下のC言語のソースを GCC でアセンブリコード出力(gcc -s hello.c)したものに相当する。
#include <ole2.h> int main( int argc, char* argv[] ) { CLSID clsid; IDispatch* pShell; IDispatch* pFolder; DISPID dispid; OLECHAR* ptName = L"BrowseForFolder"; DISPPARAMS param = { NULL, NULL, 0, 0 }; VARIANT varg[4]; VARIANT vResult; CoInitialize( NULL ); CLSIDFromProgID(L"Shell.Application", &clsid ); CoCreateInstance( &clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDispatch, (void**)&pShell); pShell->lpVtbl->GetIDsOfNames( (void*)pShell, &IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid ); VariantInit( &varg[0] ); varg[0].vt = VT_I4; varg[0].lVal = 36L; /* ssfWINDOWS */ VariantInit( &varg[1] ); varg[1].vt = VT_I4; varg[1].lVal = 0L; VariantInit( &varg[2] ); varg[2].vt = VT_BSTR; varg[2].bstrVal = SysAllocString(L"Hello, COM World!"); VariantInit( &varg[3] ); varg[3].vt = VT_I4; varg[3].lVal = 0L; param.cArgs = 4; param.rgvarg = varg; pShell->lpVtbl->Invoke( (void*)pShell, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, ¶m, &vResult, NULL, NULL ); VariantInit( &varg[0] ); VariantInit( &varg[1] ); VariantInit( &varg[2] ); VariantInit( &varg[3] ); pFolder = V_DISPATCH( &vResult ); if ( pFolder != NULL ) { pFolder->lpVtbl->Release( (void*)pFolder ); } pShell->lpVtbl->Release( (void*)pShell ); CoUninitialize(); return 0; }
コンパイル&リンク方法
C:¥> gcc -c hello.c C:¥> gcc -o hello hello.o -l ole32 -l oleaut32 -l uuid
実行結果
+----------------------------------------+ |Browse For Folder [X]| +----------------------------------------+ | Hello, COM Wolrd! | | | | +------------------------------------+ | | |[Windows] | | | | +[addins] | | | | +[AppCompat] | | | | +[AppPatch] | | | | +[assembly] | | | | : | | | | : | | | | : | | | +------------------------------------+ | | [Make New Folder] [ OK ] [Cancel] | +----------------------------------------+
-
Hello, COM(LLVM) World!
Posted on 3月 17th, 2013 by cx20
COM(LLVM)
COM(Component Object Model)はマイクロソフトの提唱するプログラム部品の仕様である。
COM を用いて開発された部品であれば言語を問わず利用することができる。
以下は LLVM Assembler による COM クライアントの例となっている。ソースコード
; ModuleID = 'hello.c' target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32" target triple = "i686-w64-mingw32" %struct._GUID = type { i32, i16, i16, [8 x i8] } %struct.IDispatch = type { %struct.IDispatchVtbl* } %struct.IDispatchVtbl = type { i32 (%struct.IDispatch*, %struct._GUID*, i8**)*, i32 (%struct.IDispatch*)*, i32 (%struct.IDispatch*)*, i32 (%struct.IDispatch*, i32*)*, i32 (%struct.IDispatch*, i32, i32, %struct.ITypeInfo**)*, i32 (%struct.IDispatch*, %struct._GUID*, i16**, i32, i32, i32*)*, i32 (%struct.IDispatch*, i32, %struct._GUID*, i32, i16, %struct.tagDISPPARAMS*, %struct.tagVARIANT*, %struct.tagEXCEPINFO*, i32*)* } %struct.ITypeInfo = type { %struct.ITypeInfoVtbl* } %struct.ITypeInfoVtbl = type { i32 (%struct.ITypeInfo*, %struct._GUID*, i8**)*, i32 (%struct.ITypeInfo*)*, i32 (%struct.ITypeInfo*)*, i32 (%struct.ITypeInfo*, %struct.tagTYPEATTR**)*, i32 (%struct.ITypeInfo*, %struct.ITypeComp**)*, i32 (%struct.ITypeInfo*, i32, %struct.tagFUNCDESC**)*, i32 (%struct.ITypeInfo*, i32, %struct.tagVARDESC**)*, i32 (%struct.ITypeInfo*, i32, i16**, i32, i32*)*, i32 (%struct.ITypeInfo*, i32, i32*)*, i32 (%struct.ITypeInfo*, i32, i32*)*, i32 (%struct.ITypeInfo*, i16**, i32, i32*)*, i32 (%struct.ITypeInfo*, i8*, i32, i16, %struct.tagDISPPARAMS*, %struct.tagVARIANT*, %struct.tagEXCEPINFO*, i32*)*, i32 (%struct.ITypeInfo*, i32, i16**, i16**, i32*, i16**)*, i32 (%struct.ITypeInfo*, i32, i32, i16**, i16**, i16*)*, i32 (%struct.ITypeInfo*, i32, %struct.ITypeInfo**)*, i32 (%struct.ITypeInfo*, i32, i32, i8**)*, i32 (%struct.ITypeInfo*, %struct.IUnknown*, %struct._GUID*, i8**)*, i32 (%struct.ITypeInfo*, i32, i16**)*, i32 (%struct.ITypeInfo*, %struct.ITypeLib**, i32*)*, void (%struct.ITypeInfo*, %struct.tagTYPEATTR*)*, void (%struct.ITypeInfo*, %struct.tagFUNCDESC*)*, void (%struct.ITypeInfo*, %struct.tagVARDESC*)* } %struct.tagTYPEATTR = type <{ %struct._GUID, i32, i32, i32, i32, i16*, i32, i32, i16, i16, i16, i16, i16, i16, i16, i16, %struct.tagTYPEDESC, %struct.tagIDLDESC }> %struct.tagTYPEDESC = type <{ %union.anon, i16, [2 x i8] }> %union.anon = type { %struct.tagTYPEDESC* } %struct.tagIDLDESC = type { i32, i16 } %struct.ITypeComp = type { %struct.ITypeCompVtbl* } %struct.ITypeCompVtbl = type { i32 (%struct.ITypeComp*, %struct._GUID*, i8**)*, i32 (%struct.ITypeComp*)*, i32 (%struct.ITypeComp*)*, i32 (%struct.ITypeComp*, i16*, i32, i16, %struct.ITypeInfo**, i32*, %union.tagBINDPTR*)*, i32 (%struct.ITypeComp*, i16*, i32, %struct.ITypeInfo**, %struct.ITypeComp**)* } %union.tagBINDPTR = type { %struct.tagFUNCDESC* } %struct.tagFUNCDESC = type <{ i32, i32*, %struct.tagELEMDESC*, i32, i32, i32, i16, i16, i16, i16, %struct.tagELEMDESC, i16, [2 x i8] }> %struct.tagELEMDESC = type <{ %struct.tagTYPEDESC, %union.anon.0 }> %union.anon.0 = type { %struct.tagIDLDESC } %struct.tagVARDESC = type <{ i32, i16*, %union.anon.9, %struct.tagELEMDESC, i16, [2 x i8], i32 }> %union.anon.9 = type { i32 } %struct.tagDISPPARAMS = type { %struct.tagVARIANT*, i32*, i32, i32 } %struct.tagVARIANT = type { %union.anon.1 } %union.anon.1 = type { %struct.anon } %struct.anon = type { i16, i16, i16, i16, %union.anon.2 } %union.anon.2 = type { i64 } %struct.tagEXCEPINFO = type { i16, i16, i16*, i16*, i16*, i32, i8*, i32 (%struct.tagEXCEPINFO*)*, i32 } %struct.IUnknown = type { %struct.IUnknownVtbl* } %struct.IUnknownVtbl = type { i32 (%struct.IUnknown*, %struct._GUID*, i8**)*, i32 (%struct.IUnknown*)*, i32 (%struct.IUnknown*)* } %struct.ITypeLib = type { %struct.ITypeLibVtbl* } %struct.ITypeLibVtbl = type { i32 (%struct.ITypeLib*, %struct._GUID*, i8**)*, i32 (%struct.ITypeLib*)*, i32 (%struct.ITypeLib*)*, i32 (%struct.ITypeLib*)*, i32 (%struct.ITypeLib*, i32, %struct.ITypeInfo**)*, i32 (%struct.ITypeLib*, i32, i32*)*, i32 (%struct.ITypeLib*, %struct._GUID*, %struct.ITypeInfo**)*, i32 (%struct.ITypeLib*, %struct.tagTLIBATTR**)*, i32 (%struct.ITypeLib*, %struct.ITypeComp**)*, i32 (%struct.ITypeLib*, i32, i16**, i16**, i32*, i16**)*, i32 (%struct.ITypeLib*, i16*, i32, i32*)*, i32 (%struct.ITypeLib*, i16*, i32, %struct.ITypeInfo**, i32*, i16*)*, void (%struct.ITypeLib*, %struct.tagTLIBATTR*)* } %struct.tagTLIBATTR = type <{ %struct._GUID, i32, i32, i16, i16, i16, [2 x i8] }> @.str = private unnamed_addr constant [16 x i16] [i16 66, i16 114, i16 111, i16 119, i16 115, i16 101, i16 70, i16 111, i16 114, i16 70, i16 111, i16 108, i16 100, i16 101, i16 114, i16 0], align 2 @.str1 = private unnamed_addr constant [18 x i16] [i16 83, i16 104, i16 101, i16 108, i16 108, i16 46, i16 65, i16 112, i16 112, i16 108, i16 105, i16 99, i16 97, i16 116, i16 105, i16 111, i16 110, i16 0], align 2 @IID_IDispatch = external constant %struct._GUID @GUID_NULL = external constant %struct._GUID @.str2 = private unnamed_addr constant [18 x i16] [i16 72, i16 101, i16 108, i16 108, i16 111, i16 44, i16 32, i16 67, i16 79, i16 77, i16 32, i16 87, i16 111, i16 114, i16 108, i16 100, i16 33, i16 0], align 2 define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { %clsid = alloca %struct._GUID, align 4 %pShell = alloca %struct.IDispatch*, align 4 %dispid = alloca i32, align 4 %ptName = alloca i16*, align 4 %param = alloca %struct.tagDISPPARAMS, align 4 %varg = alloca [4 x %struct.tagVARIANT], align 8 %vResult = alloca %struct.tagVARIANT, align 8 store i16* getelementptr inbounds ([16 x i16]* @.str, i32 0, i32 0), i16** %ptName, align 4, !tbaa !0 %1 = bitcast %struct.tagDISPPARAMS* %param to i8* call void @llvm.memset.p0i8.i32(i8* %1, i8 0, i32 16, i32 4, i1 false) %2 = call x86_stdcallcc i32 @CoInitialize(i8* null) nounwind %3 = call x86_stdcallcc i32 @CLSIDFromProgID(i16* getelementptr inbounds ([18 x i16]* @.str1, i32 0, i32 0), %struct._GUID* %clsid) nounwind %4 = bitcast %struct.IDispatch** %pShell to i8** %5 = call x86_stdcallcc i32 @CoCreateInstance(%struct._GUID* %clsid, %struct.IUnknown* null, i32 1, %struct._GUID* @IID_IDispatch, i8** %4) nounwind %6 = load %struct.IDispatch** %pShell, align 4, !tbaa !0 %7 = getelementptr inbounds %struct.IDispatch* %6, i32 0, i32 0 %8 = load %struct.IDispatchVtbl** %7, align 4, !tbaa !0 %9 = getelementptr inbounds %struct.IDispatchVtbl* %8, i32 0, i32 5 %10 = load i32 (%struct.IDispatch*, %struct._GUID*, i16**, i32, i32, i32*)** %9, align 4, !tbaa !0 %11 = call x86_stdcallcc i32 @GetUserDefaultLCID() nounwind %12 = call x86_stdcallcc i32 %10(%struct.IDispatch* %6, %struct._GUID* @GUID_NULL, i16** %ptName, i32 1, i32 %11, i32* %dispid) nounwind %13 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 0 call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %13) nounwind %14 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 0, i32 0, i32 0, i32 0 store i16 3, i16* %14, align 8, !tbaa !3 %15 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 0, i32 0, i32 0, i32 4 %16 = bitcast %union.anon.2* %15 to i32* store i32 36, i32* %16, align 8, !tbaa !4 %17 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 1 call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %17) nounwind %18 = getelementptr inbounds %struct.tagVARIANT* %17, i32 0, i32 0, i32 0, i32 0 store i16 3, i16* %18, align 8, !tbaa !3 %19 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 1, i32 0, i32 0, i32 4 %20 = bitcast %union.anon.2* %19 to i32* store i32 0, i32* %20, align 8, !tbaa !4 %21 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 2 call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %21) nounwind %22 = getelementptr inbounds %struct.tagVARIANT* %21, i32 0, i32 0, i32 0, i32 0 store i16 8, i16* %22, align 8, !tbaa !3 %23 = call x86_stdcallcc i16* @SysAllocString(i16* getelementptr inbounds ([18 x i16]* @.str2, i32 0, i32 0)) nounwind %24 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 2, i32 0, i32 0, i32 4 %25 = bitcast %union.anon.2* %24 to i16** store i16* %23, i16** %25, align 8, !tbaa !0 %26 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 3 call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %26) nounwind %27 = getelementptr inbounds %struct.tagVARIANT* %26, i32 0, i32 0, i32 0, i32 0 store i16 3, i16* %27, align 8, !tbaa !3 %28 = getelementptr inbounds [4 x %struct.tagVARIANT]* %varg, i32 0, i32 3, i32 0, i32 0, i32 4 %29 = bitcast %union.anon.2* %28 to i32* store i32 0, i32* %29, align 8, !tbaa !4 %30 = getelementptr inbounds %struct.tagDISPPARAMS* %param, i32 0, i32 2 store i32 4, i32* %30, align 4, !tbaa !5 %31 = getelementptr inbounds %struct.tagDISPPARAMS* %param, i32 0, i32 0 store %struct.tagVARIANT* %13, %struct.tagVARIANT** %31, align 4, !tbaa !0 %32 = load %struct.IDispatch** %pShell, align 4, !tbaa !0 %33 = getelementptr inbounds %struct.IDispatch* %32, i32 0, i32 0 %34 = load %struct.IDispatchVtbl** %33, align 4, !tbaa !0 %35 = getelementptr inbounds %struct.IDispatchVtbl* %34, i32 0, i32 6 %36 = load i32 (%struct.IDispatch*, i32, %struct._GUID*, i32, i16, %struct.tagDISPPARAMS*, %struct.tagVARIANT*, %struct.tagEXCEPINFO*, i32*)** %35, align 4, !tbaa !0 %37 = load i32* %dispid, align 4, !tbaa !4 %38 = call x86_stdcallcc i32 @GetUserDefaultLCID() nounwind %39 = call x86_stdcallcc i32 %36(%struct.IDispatch* %32, i32 %37, %struct._GUID* @GUID_NULL, i32 %38, i16 zeroext 1, %struct.tagDISPPARAMS* %param, %struct.tagVARIANT* %vResult, %struct.tagEXCEPINFO* null, i32* null) nounwind call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %13) nounwind call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %17) nounwind call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %21) nounwind call x86_stdcallcc void @VariantInit(%struct.tagVARIANT* %26) nounwind %40 = getelementptr inbounds %struct.tagVARIANT* %vResult, i32 0, i32 0, i32 0, i32 4 %41 = bitcast %union.anon.2* %40 to %struct.IDispatch** %42 = load %struct.IDispatch** %41, align 8, !tbaa !0 %43 = icmp eq %struct.IDispatch* %42, null br i1 %43, label %50, label %44 ; <label>:44 ; preds = %0 %45 = getelementptr inbounds %struct.IDispatch* %42, i32 0, i32 0 %46 = load %struct.IDispatchVtbl** %45, align 4, !tbaa !0 %47 = getelementptr inbounds %struct.IDispatchVtbl* %46, i32 0, i32 2 %48 = load i32 (%struct.IDispatch*)** %47, align 4, !tbaa !0 %49 = call x86_stdcallcc i32 %48(%struct.IDispatch* %42) nounwind br label %50 ; <label>:50 ; preds = %0, %44 %51 = load %struct.IDispatch** %pShell, align 4, !tbaa !0 %52 = getelementptr inbounds %struct.IDispatch* %51, i32 0, i32 0 %53 = load %struct.IDispatchVtbl** %52, align 4, !tbaa !0 %54 = getelementptr inbounds %struct.IDispatchVtbl* %53, i32 0, i32 2 %55 = load i32 (%struct.IDispatch*)** %54, align 4, !tbaa !0 %56 = call x86_stdcallcc i32 %55(%struct.IDispatch* %51) nounwind call x86_stdcallcc void @CoUninitialize() nounwind ret i32 0 } declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind declare x86_stdcallcc i32 @CoInitialize(i8*) declare x86_stdcallcc i32 @CLSIDFromProgID(i16*, %struct._GUID*) declare x86_stdcallcc i32 @CoCreateInstance(%struct._GUID*, %struct.IUnknown*, i32, %struct._GUID*, i8**) declare x86_stdcallcc i32 @GetUserDefaultLCID() declare x86_stdcallcc void @VariantInit(%struct.tagVARIANT*) declare x86_stdcallcc i16* @SysAllocString(i16*) declare x86_stdcallcc void @CoUninitialize() !0 = metadata !{metadata !"any pointer", metadata !1} !1 = metadata !{metadata !"omnipotent char", metadata !2} !2 = metadata !{metadata !"Simple C/C++ TBAA"} !3 = metadata !{metadata !"short", metadata !1} !4 = metadata !{metadata !"long", metadata !1} !5 = metadata !{metadata !"int", metadata !1}
上記コードは以下のC言語のソースを clang でアセンブリコード出力(clang -S -O4 hello.c)したものに相当する。
#include <ole2.h> int main( int argc, char* argv[] ) { CLSID clsid; IDispatch* pShell; IDispatch* pFolder; DISPID dispid; OLECHAR* ptName = L"BrowseForFolder"; DISPPARAMS param = { NULL, NULL, 0, 0 }; VARIANT varg[4]; VARIANT vResult; CoInitialize( NULL ); CLSIDFromProgID(L"Shell.Application", &clsid ); CoCreateInstance( &clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDispatch, (void**)&pShell); pShell->lpVtbl->GetIDsOfNames( (void*)pShell, &IID_NULL, &ptName, 1, GetUserDefaultLCID(), &dispid ); VariantInit( &varg[0] ); varg[0].vt = VT_I4; varg[0].lVal = 36L; /* ssfWINDOWS */ VariantInit( &varg[1] ); varg[1].vt = VT_I4; varg[1].lVal = 0L; VariantInit( &varg[2] ); varg[2].vt = VT_BSTR; varg[2].bstrVal = SysAllocString(L"Hello, COM World!"); VariantInit( &varg[3] ); varg[3].vt = VT_I4; varg[3].lVal = 0L; param.cArgs = 4; param.rgvarg = varg; pShell->lpVtbl->Invoke( (void*)pShell, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, ¶m, &vResult, NULL, NULL ); VariantInit( &varg[0] ); VariantInit( &varg[1] ); VariantInit( &varg[2] ); VariantInit( &varg[3] ); pFolder = V_DISPATCH( &vResult ); if ( pFolder != NULL ) { pFolder->lpVtbl->Release( (void*)pFolder ); } pShell->lpVtbl->Release( (void*)pShell ); CoUninitialize(); return 0; }
コンパイル&リンク方法
C:¥> clang -o hello hello.ll -l ole32 -l oleaut32 -l uuid
実行結果
+----------------------------------------+ |Browse For Folder [X]| +----------------------------------------+ | Hello, COM Wolrd! | | | | +------------------------------------+ | | |[Windows] | | | | +[addins] | | | | +[AppCompat] | | | | +[AppPatch] | | | | +[assembly] | | | | : | | | | : | | | | : | | | +------------------------------------+ | | [Make New Folder] [ OK ] [Cancel] | +----------------------------------------+
-
Hello, Win32 API(GAS) World!
Posted on 3月 14th, 2013 by cx20
Win32 API(GAS)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は GAS からの呼出し例である。ソースコード(GAS)
.file "hello.c" .def ___main; .scl 2; .type 32; .endef .section .rdata,"dr" LC0: .ascii "Hello, World!
上記コードは、下記の C のソースを MinGW版 GCC にてアセンブリコード出力(gcc -S hello.c)したものである。
ソースコード(C言語)
#include <windows.h> int main( int argc, char* argv[] ) { MessageBox( NULL, "Hello, Win32 API World!", "Hello, World!", MB_OK ); return 0; }
コンパイル方法(MinGW版 gcc)
C:¥> gcc -c hello.s C:¥> gcc -o hello hello.o
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API World! --------------------------- OK ---------------------------
-
Hello, Win32 API(LLVM) World!
Posted on 3月 13th, 2013 by cx20
Win32 API(LLVM)
Win32 API は、Windows の機能にアクセスする為の API(Application Programming Interface)である。
以下は LLVM Assembler による呼出し例である。ソースコード(LLVM)
; ModuleID = 'hello.c' target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32" target triple = "i686-w64-mingw32" %struct.HWND__ = type { i32 } @.str = private unnamed_addr constant [24 x i8] c"Hello, Win32 API World!
上記コードは、下記の C のソースを clang にてアセンブリコード出力(clang -S -O4 hello.c)したものである。
ソースコード(C言語)
#include <windows.h> int main( int argc, char* argv[] ) { MessageBox( NULL, "Hello, Win32 API World!", "Hello, World!", MB_OK ); return 0; }
コンパイル方法(MinGW版 clang)
C:¥> clang -o hello hello.ll
実行結果
--------------------------- Hello, World! --------------------------- Hello, Win32 API World! --------------------------- OK ---------------------------
-
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! | | | | | | | | | | | | | | | | | | | +------------------------------------------+
-
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] | +----------------------------------------+
-
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 ---------------------------
-
Hello, Java VM Assembler World!
Posted on 1月 6th, 2012 by cx20
Java VM Assembler
Java VM アセンブラは Java VM の中間コード(バイトコード)を生成するアセンブラである。
主要な Java VM アセンブラとしては、Jasmin 等がある。
ソースコード
.class public Hello .super java/lang/Object .method public ()V aload_0 invokespecial java/lang/Object/()V return .end method .method public static main([Ljava/lang/String;)V .limit stack 2 getstatic java/lang/System/out Ljava/io/PrintStream; ldc "Hello, Java VM World!" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V return .end method
上記コードは以下の Java のソースに対応する。
クラスファイルを tinapoc と言った逆アセンブラや javap で逆アセンブル(javap -c Hello)することでアセンブリコードを得られる。public class Hello { public static void main( String[] args ) { System.out.println( "Hello, Java VM World!" ); } }
コンパイル&実行方法(Jasmin)
$ java -jar jasmin.jar Hello.j $ java Hello
実行結果
Hello, Java VM World!
-
Hello, CASL World!
Posted on 1月 5th, 2012 by cx20
CASL
CASL は情報処理技術者試験の為に仕様策定されたアセンブリ言語である。仮想計算機 COMET 上で動作する。
2001年より仕様改訂され現在は COMMET II / CASL II が利用されている。ソースコード
コンパイル&実行方法(YACASL2)
$ casl2 -Ohello.o hello.cas $ comet2 hello.o
コンパイル&実行(JPA CASL II シミュレータ)
$ java -jar casl2.jar hello.cas $ java -jar run.jar hello.obj
実行結果
Hello, CASL World!
-
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!