### Author Topic: Asmc source and binaries  (Read 33722 times)

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #45 on: July 15, 2017, 01:00:24 AM »
Here's another version of the dll-to-lib tools. This converts all dll-files in the system32 directory by default. There was more than 2000 files there (Win7-64).
Code: [Select]
`SYSDLL creates import from %windir%/system32/[<mask>|*].dllUsage: SYSDLL <options> [<mask>] /def - create .def files /lib - create .lib files /inc - create .inc files`
Example:
Code: [Select]
`ifdef __PE__    .x64    .model flat, fastcallendifinclude inc\msvcrt.inc    .codemain proc    .if fopen("test.asm", "rt")        mov rsi,rax        .if malloc(512)            mov rdi,rax            .while fgets(rdi, 512, rsi)                printf(rdi)            .endw            free(rdi)        .endif        fclose(rsi)    .endif    exit(0)main endp    end main`
Create library and include file (and directories):
Code: [Select]
`SYSDLL /lib msvcrtSYSDLL /inc msvcrt`
Assemble:
Code: [Select]
`asmc /win64 test.asminc\msvcrt.inc(1010) : error A2034: must be in segment block inc\msvcrt.inc(1010): Included by  test.asm(11): Main line codeinc\msvcrt.inc(1014) : error A2034: must be in segment block inc\msvcrt.inc(1014): Included by  test.asm(11): Main line code`
Fixing the include file:
Code: [Select]
`difftime proto :vararg;div proto :varargexit proto :varargexp proto :varargexpf proto :vararg;fabs proto :varargfclose proto :vararg`
Code: [Select]
`asmc /win64 test.asmlinkw lib lib\msvcrt.lib file test.obj`
Code: [Select]
`asmc /pe /D__PE__ test.asm`

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #46 on: October 07, 2017, 10:03:26 PM »
Added __PE__ to the -pe switch

makefile
Code: [Select]
`##  __PE__ auto defined if switch -pe used#test.exe:    asmc /q /pe \$*.asm    \$@    del \$@    asmc /q /pe /D_WIN64 \$*.asm    \$@    del \$@`
This build a 32 and 64-bit version of the Tutorial 16: Event Object sample.

Code: [Select]
`include windows.incinclude winres.incifdef _WIN64option win64:3APPNAME   equ <"Win64 ASM Event Example">CLASSNAME equ <"Win64ASMEventClass">elserax equ <eax>rbx equ <ebx>rcx equ <ecx>APPNAME   equ <"Win32 ASM Event Example">CLASSNAME equ <"Win32ASMEventClass">endifIDM_START_THREAD    equ 1IDM_STOP_THREAD     equ 2IDM_EXIT            equ 3IDR_MAINMENU        equ 30WM_FINISH           equ WM_USER+100h.dataEventStop   BOOL FALSEhMenu       HANDLE ?hwnd        HANDLE ?hEventStart HANDLE ?hThread     HANDLE ?ThreadID    dd ?.codeThrdProc proc    .while 1        WaitForSingleObject(hEventStart, INFINITE)        mov ecx,600000000        .while ecx            .if EventStop != TRUE                add eax,eax                dec ecx            .else                MessageBox(hwnd, "The thread is stopped",                        "The calculation is completed!", MB_OK)                mov EventStop,FALSE                .continue(1)            .endif        .endw        PostMessage(hwnd, WM_FINISH, 0, 0)        EnableMenuItem(hMenu, IDM_START_THREAD, MF_ENABLED)        EnableMenuItem(hMenu, IDM_STOP_THREAD, MF_GRAYED)    .endw    retThrdProc endpWndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM    .switch uMsg      .case WM_DESTROY        PostQuitMessage(NULL)        xor eax,eax        .endc      .case WM_COMMAND        .if !lParam ; menu commands            movzx eax,word ptr wParam            .switch eax              .case IDM_START_THREAD                SetEvent(hEventStart)                EnableMenuItem(hMenu, IDM_START_THREAD, MF_GRAYED)                EnableMenuItem(hMenu, IDM_STOP_THREAD, MF_ENABLED)                .endc              .case IDM_STOP_THREAD                mov EventStop,TRUE                EnableMenuItem(hMenu, IDM_START_THREAD, MF_ENABLED)                EnableMenuItem(hMenu, IDM_STOP_THREAD, MF_GRAYED)                .endc              .case IDM_EXIT                DestroyWindow(hWnd)                .endc            .endsw        .endif        xor eax,eax        .endc      .case WM_CREATE        mov hEventStart,CreateEvent(NULL, FALSE, FALSE, NULL)        mov hThread,CreateThread(NULL, NULL, &ThrdProc, NULL, NORMAL_PRIORITY_CLASS, &ThreadID)        CloseHandle(hThread)        xor eax,eax        .endc      .case WM_FINISH        MessageBox(0, "The calculation is completed!", APPNAME, MB_OK)        xor eax,eax        .endc      .default        DefWindowProc(hWnd, uMsg, wParam, lParam)    .endsw    retWndProc endpWinMain proc WINAPI hInst: HINSTANCE,     hPrevInstance: HINSTANCE,         lpCmdLine: LPSTR,          nShowCmd: SINT    local wc:WNDCLASSEX    local msg:MSG    mov wc.cbSize,SIZEOF WNDCLASSEX    mov wc.style,CS_HREDRAW or CS_VREDRAW    mov wc.lpfnWndProc,WndProc    mov rcx,hInst    xor eax,eax    mov wc.cbClsExtra,eax    mov wc.cbWndExtra,eax    mov wc.hInstance,rcx    mov wc.hbrBackground,COLOR_WINDOW    mov wc.lpszMenuName,IDR_MAINMENUifdef _WIN64    lea rax,@CStr("Win64ASMEventClass")else    lea rax,@CStr("Win32ASMEventClass")endif    mov wc.lpszClassName,rax    mov wc.hIcon,LoadIcon(0, IDI_APPLICATION)    mov wc.hIconSm,rax    mov wc.hCursor,LoadCursor(0, IDC_ARROW)    RegisterClassEx(&wc)    mov hwnd,CreateWindowEx(WS_EX_CLIENTEDGE, CLASSNAME,        APPNAME, WS_OVERLAPPEDWINDOW or WS_VISIBLE,        CW_USEDEFAULT, CW_USEDEFAULT, 400, 200, 0, 0, hInst, 0)    ShowWindow(hwnd, SW_SHOWNORMAL)    UpdateWindow(hwnd)    mov hMenu,GetMenu(hwnd)    .while GetMessage(&msg, NULL, 0, 0)        TranslateMessage(&msg)        DispatchMessage(&msg)    .endw    mov rax,msg.wParam    retWinMain endpWinStart proc    mov rbx,GetModuleHandle(0)    ExitProcess(WinMain(rbx, 0, GetCommandLine(), SW_SHOWDEFAULT))WinStart endpRCBEGIN    RCTYPES 1    RCENTRY RT_MENU    RCENUMN 1    RCENUMX IDR_MAINMENU    RCLANGX LANGID_US    MENUBEGIN      MENUNAME "&Thread", MF_END        MENUITEM IDM_START_THREAD, "&Run Thread"        MENUITEM IDM_STOP_THREAD,  "&Stop Thread"        SEPARATOR        MENUITEM IDM_EXIT, "E&xit", MF_END    MENUENDRCEND    end WinStart`
Some stats from the current source base:
Code: [Select]
`2457 .ASM files - 194530 lines 153 .INC files - 115220 lines 276 .C   files - 121254 lines 783 .LIB files1425 macros`

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #47 on: October 27, 2017, 01:23:18 AM »

Added a simple Hex editor to Doszip assigned to Ctrl-F4. In addition to the standard mode there is also a Class mode with the possibility to define a line-based struct of data. This may be a string or byte (hex) array, or integer value of size 1 to 8, signed/unsigned or hex.

Formatted struct's may be saved and loaded from disk at specific offsets.
Code: [Select]
`00000068    PE···············································  CHAR[2]0000006A    00006486                                           BYTE[4]0000006E    0002                                               WORD(hexadecimal)00000070    1509026722                                         DWORD(unsigned)00000074    0                                                  DWORD(signed)00000078    0                                                  DWORD(signed)0000007C    00F0                                               WORD(hexadecimal)0000007E    012F                                               WORD(hexadecimal)00000080    0B02                                               BYTE[2]00000082    5                                                  BYTE(signed)00000083    1                                                  BYTE(signed)00000084    512                                                DWORD(unsigned)00000088    0                                                  DWORD(unsigned)0000008C    0                                                  DWORD(unsigned)00000090    4096                                               DWORD(unsigned)00000094    4096                                               DWORD(unsigned)00000098    0000000140000000                                   QWORD(hexadecimal)000000A0    4096                                               DWORD(signed)000000A4    512                                                DWORD(signed)000000A8    4                                                  WORD(signed)000000AA    0                                                  WORD(signed)000000AC    0                                                  WORD(signed)000000AE    0                                                  WORD(signed)000000B0    4                                                  WORD(signed)000000B2    0                                                  WORD(signed)000000B4    0                                                  DWORD(signed)000000B8    12288                                              DWORD(signed)000000BC    512                                                DWORD(signed)000000C0    0                                                  DWORD(signed)000000C4    0003                                               WORD(hexadecimal)000000C6    0000                                               WORD(hexadecimal)000000C8    1048576                                            QWORD(unsigned)000000D0    4096                                               QWORD(unsigned)000000D8    1048576                                            QWORD(unsigned)`
Added two switches to Asmc for using -pe.
-cui -- same as LINK /subsystem:console (default)
-gui -- same as LINK /subsystem:windows

This sets .Subsystem to IMAGE_SUBSYSTEM_WINDOWS_CUI or IMAGE_SUBSYSTEM_WINDOWS_GUI.

The combination of -pe -win64 will also set the .ImageBase to 0x140000000, default is 0x400000.

Asmc now adapts to ml64 if a simplified segment or a function prototype is found and no model or language defined. Additional [x|y]mm16..31 and zmm registers with a NASM-style {evex} prefix and implementation are also added.

This will now assemble to 64-bit fastcall:
Code: [Select]
`    .code    vaddps  xmm0,xmm1,[rax]     ; normal    vpaddsb xmm0,xmm1,xmm2    vcomisd xmm0,xmm1    vaddps  xmm16,xmm1,[rax]    ; prefix    vpaddsb xmm20,xmm0,xmm1    vcomisd xmm0,xmm31    {evex} vaddps  xmm0,xmm1,[rax]    {evex} vpaddsb xmm0,xmm1,xmm2    {evex} vcomisd xmm0,xmm1    end`
Code: [Select]
`   0: c5 f0 58 00          vaddps xmm0,xmm1,XMMWORD PTR [rax]   4: c5 f1 ec c2          vpaddsb xmm0,xmm1,xmm2   8: c5 f9 2f c1          vcomisd xmm0,xmm1   c: 62 e1 74 08 58 00    vaddps xmm16,xmm1,XMMWORD PTR [rax]  12: 62 e1 7d 08 ec e1    vpaddsb xmm20,xmm0,xmm1  18: 62 91 fd 08 2f c7    vcomisd xmm0,xmm31  1e: 62 f1 74 08 58 00    vaddps xmm0,xmm1,XMMWORD PTR [rax]  24: 62 f1 75 08 ec c2    vpaddsb xmm0,xmm1,xmm2  2a: 62 f1 fd 08 2f c1    vcomisd xmm0,xmm1`

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #48 on: November 13, 2017, 06:18:50 AM »
Had a hardware meltdown here so now I have a cute little Fujitsu box installed. Well, been working on the AVX-512 implementation and finally get GitHup up and pushed the latest changes.

I wrote a lengthy test case for the implementation mostly taken from GAS and NASM. The binary output is bit-compatible with NASM and thus disassemble correctly with objdump.

There's not much code added for the implementation but it does however add a lot of instructions and inflate the tables. The hash tables is now increased but now all sizes are set to a power of two for convenience. Also, the reserved word table is now forced low-case to skip case testing on symbols. A simple benchmark of the 7000-lines test case compare to NASM:
Code: [Select]
`   31 ClockTicks: asmc -q -bin a.asm  156 ClockTicks: nasm n.asm`
The math test compare to previous version:
Code: [Select]
`3806 ClockTicks: asmc225.exe -q real_math.asm3651 ClockTicks: \asmc\bin\asmc.exe -q real_math.asm6287 ClockTicks: \jwasm\jwasm.exe -q real_math.asm`
312832 - version 2.25
333312 - version 2.26

Code: [Select]
`8 16 32 64 128 256 5121 2 4 8 10 16 32 64AL AX EAX RAX XMM0 YMM0 ZMM0   REAL10 REAL4 REAL8 REAL16 YMMWORD ZMMWORDBYTE WORD DWORD QWORD OWORD YWORD ZWORD`

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #49 on: November 16, 2017, 10:29:27 AM »

A label is defined public if declared outside a procedure with a double colon. This simplify bear-bone  declarations, especially in 64-bit.

Code: [Select]
`.codepublic_label::    nop    ret    end`
Code: [Select]
`; Mode: 64 bits; Syntax: MASM/ML64; Instruction set: 8086, x64public public_label_text   SEGMENT PARA 'CODE'                             ; section number 1public_label PROC        nop                                             ; 0000 _ 90        ret                                             ; 0001 _ C3public_label ENDP_text   ENDS`

#### Vortex

• Member
• Posts: 2059
##### Re: Asmc source and binaries
« Reply #50 on: November 17, 2017, 06:09:38 AM »
Hi nidud,

Sorry for the late reply. Testing sysdll :

Code: [Select]
`sysdll.exe /def C:\WINDOWS\SysWOW64\msvcrt.dllsysdll.exe /def C:\WINDOWS\System32\msvcrt.dllsysdll.exe /inc C:\WINDOWS\SysWOW64\msvcrt.dllsysdll.exe /inc C:\WINDOWS\System32\msvcrt.dllsysdll.exe /lib C:\WINDOWS\SysWOW64\msvcrt.dllsysdll.exe /lib C:\WINDOWS\System32\msvcrt.dll`
I get three empty folders named def, inc and lib.  OS : Win XP 64-bit  Same problem on Win 7 64-bit

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #51 on: November 17, 2017, 06:32:35 AM »
Looking at the source code the wild arg seems to be the actual file name:
Code: [Select]
`        sprintf(rdi, "%s\\system32\\%s.dll", rax, &wild)`
This seems to work:

sysdll /inc msvcrt
sysdll /def msvcrt
sysdll /lib msvcrt

./def/msvcrt.def:
Code: [Select]
`LIBRARY msvcrtEXPORTS"_CrtCheckMemory""_CrtDbgBreak"`
./inc/msvcrt.inc:
Code: [Select]
`includelib msvcrt.lib_CrtCheckMemory proto :vararg_CrtDbgBreak proto :vararg_CrtDbgReport proto :vararg`
« Last Edit: November 28, 2017, 12:48:52 AM by nidud »

#### Vortex

• Member
• Posts: 2059
##### Re: Asmc source and binaries
« Reply #52 on: November 17, 2017, 06:58:34 AM »
Hi nidud,

Thanks for the info. The tool works as you explained.

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #53 on: November 28, 2017, 02:59:20 AM »
Did some cleanup in the GitHup source directory so some of the direct links posted may now fail. This was done to organize and improve the regression test for the libraries.

Wininc related source are now tested separately where most of the samples do not use libc and assembles with the -pe switch. Some more features are added both for LINKW and the include files to separate console/gui builds.

The -gui switch will now define __GUI__ and this will create a startup calling [w]WinMain() as oppose to [w]main() in console mode. In addition to this the switch -ws now defines _UNICODE.

• Now as the maximum line size is increased to 2048 bytes to accommodate large string declarations and recursive HLL parsing, internal procedures may use up to three lines and thus create a stack fault if the page is not committed. Some of these procedures now use alloca() to prevent this.
• Given label:opcode is always broken in Asmc the added line was missing from the list file.
• The switch /assert is added -- same as .assert:on
• Asmc extended immediate values to 64-bit in VARARG arguments if high DWORD was not -1. This restriction is now removed.

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #54 on: December 06, 2017, 09:42:33 AM »
Added some more support for invoking function pointers.

struct.funcptr(...)
[reg].struct.funcptr(...)
assume reg:ptr struct
[reg].funcptr(...)

Example:
Code: [Select]
`;; http://ube43.wix.com/directxers/apps/blog/directx-9-tutorial-1-ein-fenster;;; Every windows application needs to include thisinclude windows.incinclude tchar.inc;; Every Direct3D application thisinclude d3d9.inc.datag_bContinue dd TRUE.code;; Besides the main function, there must be a message processing functionMsgProc proc WINAPI hWnd:HWND, msg:UINT, wParam:WPARAM, lParam:LPARAM    .switch(msg)      .case WM_DESTROY:        PostQuitMessage( 0 )        mov g_bContinue,FALSE        .endc      .default        DefWindowProc( hWnd, msg, wParam, lParam )    .endsw    retMsgProc endp;; The entry point of a windows application is the WinMain functionWinMain proc WINAPI uses rsi rdi rbx r12 hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPSTR, nShowCmd:SINT    ;; Create a window class.    local wc:WNDCLASSEX    local hWnd:HWND    ;local pD3D:LPDIRECT3D9    local d3dpp:D3DPRESENT_PARAMETERS    local pd3dDevice:LPDIRECT3DDEVICE9    local msg:MSG    xor eax,eax    mov pd3dDevice,rax    lea rdi,wc    mov ecx,sizeof(WNDCLASSEX)    rep stosb    mov wc.cbSize,sizeof(WNDCLASSEX)    mov wc.style,CS_CLASSDC    lea rax,MsgProc    mov wc.lpfnWndProc,rax    lea rax,@CStr("Direct3D Window")    mov wc.lpszClassName,rax    mov wc.hInstance,GetModuleHandle(NULL)    ;;Register the window class.    RegisterClassEx( &wc );    ;; Create the application's window.    mov hWnd,CreateWindowEx(0, "Direct3D Window", "DirectXers - D3D9 Tutorial 1",        WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, GetDesktopWindow(), NULL, wc.hInstance, NULL )    ShowWindow(hWnd,SW_SHOW)    .repeat        ;; Create the Direct3D Object        .if !Direct3DCreate9(D3D_SDK_VERSION)            mov eax,E_FAIL            .break        .endif        mov rbx,rax        mov rdi,[rax]        assume rdi: ptr IDirect3D9        ;; Setup the device presentation parameters        ZeroMemory( &d3dpp, sizeof(d3dpp) )        mov d3dpp.Windowed,TRUE        mov d3dpp.SwapEffect,D3DSWAPEFFECT_DISCARD        mov d3dpp.BackBufferFormat,D3DFMT_UNKNOWN        ;; The final step is to use the IDirect3D9::CreateDevice method to create the Direct3D device, as illustrated in the        ;; following code example.        .ifs [rdi].CreateDevice(rbx, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice ) < 0            MessageBox(hWnd, "No HAL HARDWARE_VERTEXPROCESSING! Sample will exit!", NULL, 0);            [rdi].Release(rbx)            mov eax,E_FAIL            .break        .endif        mov rax,pd3dDevice        mov rsi,[rax]        mov r12,rax        assume rsi: ptr IDirect3DDevice9        .while ( g_bContinue )            ;; Clear render region with blue            [rsi].Clear( r12, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0, 0 )            ;; before rendering something, you have to call this            [rsi].BeginScene( r12 );            ;;            ;; rendering of scene objects happens her            ;;            ;; now end the scene            [rsi].EndScene( r12 );            ;; update screen = swap front and backbuffer            [rsi].Present( r12, NULL, NULL, NULL, NULL)            ;; A window has to handle its messages.            TranslateMessage( &msg );            DispatchMessage( &msg );            PeekMessage(&msg, 0, 0, 0, PM_REMOVE)        .endw        ;; Do not forget to clean up here        [rsi].Release( r12 );        [rdi].Release( rbx )        xor eax,eax    .until 1    retWinMain endp    end _tstart`
The C expansion of the interface class:
Code: [Select]
`typedef struct IClassFactory{     const struct IClassFactoryVtbl FAR* lpVtbl;} IClassFactory;#define IDirect3D9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)`
This means the current macro implementation will not work in assembly. Not sure what or how to do this, maybe add a register:
Code: [Select]
`IDirect3D9_QueryInterface macro p,a,b mov rax,[p] ; assuming register exitm<[rax].IDirect3D9.QueryInterface(p,a,b)> endm`
Well, the assembler will now handle the calls but the include files needs some update. The direct access as in the sample may also be simpler than using the macros but I need to do some more testing to see how it plays out.

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #55 on: December 09, 2017, 02:27:23 AM »
Added direct usage of pointers and removed the macros. Using registers will still work as above but this seems to be simpler.
Code: [Select]
`    p.QueryInterface(1, 2)`
Expands to:
Code: [Select]
`    mov     rcx, qword ptr [p]    mov     rdx, 1                mov     r8, 2                 mov     rax, qword ptr [rcx]    call    qword ptr [rax]     `
32-bit:
Code: [Select]
`    push    2                      push    1                      push    dword ptr [_p]         mov     eax, dword ptr [_p]    mov     eax, dword ptr [eax]    call    dword ptr [eax]`
Added d3dx9 include files and a few more examples. There seems to be a lot of these dll-files. The sample worked using d3dx9_40.dll so this is used as default import (assuming this is the version number).

The test samples was taken from this site:
http://ube43.wix.com/directxers/apps/blog/directx-9-tutorial-1-ein-fenster

Second sample using pointers:
Code: [Select]
`;; Every windows application needs to include thisinclude windows.incinclude tchar.inc;; Every Direct3D application thisinclude d3d9.incinclude d3dx9.inc.datag_lpEffect  LPD3DXEFFECT NULLg_lpVertexBuffer LPDIRECT3DVERTEXBUFFER9 NULLg_ShaderMatrix D3DXMATRIX <>g_bContinue dd TRUE;;Definition of the Vertex Format including position and diffuse colorD3DFVF_COLOREDVERTEX equ (D3DFVF_XYZ or D3DFVF_DIFFUSE)COLORED_VERTEX STRUCx           FLOAT ?     ;; Positiony           FLOAT ?z           FLOAT ?color       dd ?        ;; ColorCOLORED_VERTEX ENDS.code;; Besides the main function, there must be a message processing functionMsgProc proc WINAPI hWnd:HWND, msg:UINT, wParam:WPARAM, lParam:LPARAM    .switch(msg)      .case WM_DESTROY:        PostQuitMessage( 0 )        mov g_bContinue,FALSE        .endc      .default        DefWindowProc( hWnd, msg, wParam, lParam )    .endsw    retMsgProc endp;; The entry point of a windows application is the WinMain functionWinMain proc WINAPI uses rdi hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPSTR, nShowCmd:SINT    ;; Create a window class.    local wc:WNDCLASSEX    local hWnd:HWND    local pD3D:LPDIRECT3D9    local d3dpp:D3DPRESENT_PARAMETERS    local pd3dDevice:LPDIRECT3DDEVICE9    local msg:MSG    local uiBufferSize:UINT    local pVertices:ptr COLORED_VERTEX    local uiPasses:UINT    xor eax,eax    mov pd3dDevice,rax    lea rdi,wc    mov ecx,sizeof(WNDCLASSEX)    rep stosb    mov wc.cbSize,sizeof(WNDCLASSEX)    mov wc.style,CS_CLASSDC    lea rax,MsgProc    mov wc.lpfnWndProc,rax    lea rax,@CStr("Direct3D Window")    mov wc.lpszClassName,rax    mov wc.hInstance,GetModuleHandle(NULL)    ;;Register the window class.    RegisterClassEx( &wc );    ;; Create the application's window.    mov hWnd,CreateWindowEx(0, "Direct3D Window", "DirectXers - D3D9 Tutorial 2",        WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, GetDesktopWindow(), NULL, wc.hInstance, NULL )    ShowWindow( hWnd, SW_SHOW )    .repeat        ;; Create the Direct3D Object        .if !Direct3DCreate9( D3D_SDK_VERSION )            mov eax,E_FAIL            .break        .endif        mov pD3D,rax        ;; Setup the device presentation parameters        ZeroMemory( &d3dpp, sizeof(d3dpp) )        mov d3dpp.Windowed,TRUE        mov d3dpp.SwapEffect,D3DSWAPEFFECT_DISCARD        mov d3dpp.BackBufferFormat,D3DFMT_UNKNOWN        ;; The final step is to use the IDirect3D9::CreateDevice method to create the Direct3D device, as illustrated in the        ;; following code example.        .ifd pD3D.CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice )            MessageBox(hWnd, "No HAL HARDWARE_VERTEXPROCESSING! Sample will exit!", NULL, 0);            pD3D.Release()            mov eax,E_FAIL            .break        .endif        ;; set the vertex buffer size 4 vertices * vertex structure size        mov uiBufferSize,4*sizeof(COLORED_VERTEX)        ;; create the buffer        .ifd pd3dDevice.CreateVertexBuffer( uiBufferSize,            D3DUSAGE_WRITEONLY, D3DFVF_COLOREDVERTEX, D3DPOOL_DEFAULT, &g_lpVertexBuffer, NULL )            mov eax,E_FAIL            .break        .endif        ;; lock the buffer for writing        .ifd g_lpVertexBuffer._Lock( 0, uiBufferSize, &pVertices, 0 )            mov eax,E_FAIL            .break        .endif        ;; write the vertices. Here a simple rectangle        mov rcx,pVertices        assume rcx: ptr COLORED_VERTEX        mov [rcx].x,-1.0    ;; left        mov [rcx].y,-1.0    ;; bottom        mov [rcx].z,0.0        mov [rcx].color,0xffff0000  ;; red        add rcx,COLORED_VERTEX        mov [rcx].x,-1.0    ;; left        mov [rcx].y,1.0     ;; top        mov [rcx].z,0.0        mov [rcx].color,0xff0000ff  ;; blue        add rcx,COLORED_VERTEX        mov [rcx].x,1.0     ;; right        mov [rcx].y,-1.0    ;; bottom        mov [rcx].z,0.0        mov [rcx].color,0xff00ff00  ;; green        add rcx,COLORED_VERTEX        mov [rcx].x,1.0     ;; right        mov [rcx].y,1.0     ;; top        mov [rcx].z,0.0        mov [rcx].color,0xffffffff  ;; white        assume rcx: nothing        ;; unlock the buffer        g_lpVertexBuffer.Unlock()        ;; set the Vertex Format        pd3dDevice.SetFVF( D3DFVF_COLOREDVERTEX )        ;; transfer the buffer to the gpu        pd3dDevice.SetStreamSource( 0, g_lpVertexBuffer, 0, sizeof(COLORED_VERTEX) )        ;; create an effect        .ifd D3DXCreateEffectFromFile( pd3dDevice, "Effect.fx", NULL,            NULL, D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, NULL, &g_lpEffect, NULL )            mov eax,E_FAIL            .break        .endif        lea rcx,g_ShaderMatrix        D3DXMatrixIdentity(rcx)        g_lpEffect.SetMatrix( "ShaderMatrix", &g_ShaderMatrix )        .while ( g_bContinue )            ;; Clear render region with blue            pd3dDevice.Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0, 0 )            ;; before rendering something, you have to call this            pd3dDevice.BeginScene()            ;; rendering of scene objects happens her            mov uiPasses,0            g_lpEffect.Begin( &uiPasses, 0 )            .for ( edi = 0: edi < uiPasses: edi++ )                ;; render an effect pass                g_lpEffect.BeginPass( edi )                ;; render the rectangle                pd3dDevice.DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 )                g_lpEffect.EndPass()            .endf            g_lpEffect._End()            ;; now end the scene            pd3dDevice.EndScene()            ;; update screen = swap front and backbuffer            pd3dDevice.Present( NULL, NULL, NULL, NULL )            ;; A window has to handle its messages.            TranslateMessage( &msg );            DispatchMessage( &msg );            PeekMessage(&msg, 0, 0, 0, PM_REMOVE)        .endw        ;; Do not forget to clean up here        pd3dDevice.Release()        pD3D.Release()        g_lpEffect.Release()        g_lpVertexBuffer.Release()        xor eax,eax    .until 1    retWinMain endp    end _tstart`

#### Vortex

• Member
• Posts: 2059
##### Re: Asmc source and binaries
« Reply #56 on: December 10, 2017, 11:28:40 PM »
Hi nidud,

I am trying to convert a COM example from Masm to the new Asmc syntax supporting the invocation of function pointers ( testing Asmc Version 2.27C ) :

Code: [Select]
`.386.model flat,stdcalloption casemap:noneoption wstring:oninclude     \masm32\include\windows.incinclude     \masm32\include\kernel32.incinclude     \masm32\include\ole32.incinclude     SetWallpaper.incincludelib  \masm32\lib\kernel32.libincludelib  \masm32\lib\ole32.lib; LPActDesk TYPEDEF PTR IActiveDesktop.dataCLSID_IActiveDesktop    GUID sCLSID_IActiveDesktopIID_IActiveDesktop      GUID sIID_IActiveDesktopDesktopImg dw 'test.bmp',0.data?wpo         WALLPAPEROPT <>pAD         dd ?.codestart:    invoke      CoInitialize,NULL    invoke      CoCreateInstance,ADDR CLSID_IActiveDesktop,NULL,\                 CLSCTX_INPROC_SERVER,ADDR IID_IActiveDesktop,ADDR pAD                mov         edx,OFFSET wpo    mov         WALLPAPEROPT.dwSize[edx],SIZEOF(WALLPAPEROPT)    mov         WALLPAPEROPT.dwStyle[edx],WPSTYLE_CENTER    mov         eax,pAD    [eax].IActiveDesktop.SetWallpaper(ADDR DesktopImg,0)    coinvoke    pAD,IActiveDesktop,SetWallpaper,OFFSET DesktopImg,0    coinvoke    pAD,IActiveDesktop,SetWallpaperOptions,OFFSET wpo,0    coinvoke    pAD,IActiveDesktop,ApplyChanges,AD_APPLY_ALL    coinvoke    pAD,IActiveDesktop,Release    invoke      CoUninitialize        invoke      ExitProcess,0END start`
I get the following error message :

Code: [Select]
`[eax].IActiveDesktop.SetWallpaper(ADDR DesktopImg,0)`
Code: [Select]
`SetWallpaper.asm(42) : error A2190: INVOKE requires prototype for procedure`
Also as an alternative syntax, is it possible to use this expression with some modifications in the source code?

Code: [Select]
`pAD.SetWallpaper(ADDR DesktopImg,0)`
My intention is to preserve the definition of the IActiveDesktop interface like the following while using the new function pointer invocation syntax  :

Code: [Select]
`IActiveDesktop STRUCT    QueryInterface          dd ?    AddRef                  dd ?    Release                 dd ?    ApplyChanges            dd ?    GetWallpaper            dd ?    SetWallpaper            dd ?    GetWallpaperOptions     dd ?    SetWallpaperOptions     dd ?    GetPattern              dd ?    SetPattern              dd ?    GetDesktopItemOptions   dd ?    SetDesktopItemOptions   dd ?    AddDesktopItem          dd ?    AddDesktopItemWithUI    dd ?    ModifyDesktopItem       dd ?    RemoveDesktopItem       dd ?    GetDesktopItemCount     dd ?    GetDesktopItem          dd ?    GetDesktopItemByID      dd ?    GenerateDesktopItemHtml dd ?    AddUrl                  dd ?    GetDesktopItemBySource  dd ?IActiveDesktop ENDS`

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #57 on: December 14, 2017, 05:42:51 AM »
I'v updated and added more include files using the STDMETHOD macro and added a SetWallpaper sample from the code above.
Code: [Select]
`include windows.incinclude wininet.incinclude shlobj.incBITMAP0 equ <L"%SystemRoot%\\web\\wallpaper\\Windows\\img0.jpg">BITMAP1 equ <L"%AsmcDir%\\source\\test\\wininc\\SetWallpaper\\test.bmp">.dataCLSID_ActiveDesktop GUID _CLSID_ActiveDesktopIID_IActiveDesktop  GUID _IID_IActiveDesktop.codemain proc  local w:WALLPAPEROPT  local p:LPACTIVEDESKTOP    CoInitialize(NULL)    CoCreateInstance(&CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, &IID_IActiveDesktop, &p)    p.SetWallpaper( BITMAP0, 0 )    mov w.dwSize,sizeof(WALLPAPEROPT)    mov w.dwStyle,WPSTYLE_CENTER    p.SetWallpaperOptions( &w, 0 )    p.ApplyChanges( AD_APPLY_ALL )    p.Release()    CoUninitialize()    retmain endp    end`
Also as an alternative syntax, is it possible to use this expression with some modifications in the source code?

Code: [Select]
`pAD.SetWallpaper(ADDR DesktopImg,0)`
My intention is to preserve the definition of the IActiveDesktop interface like the following while using the new function pointer invocation syntax  :

Code: [Select]
`  local p:LPDIRECT3D9    p.QueryInterface(1, 2)*   invoke [rax].IDirect3D9.QueryInterface, p, 1, 2`
The struct name is extracted from what the pointer points to and invoke needs a prototype so the functions needs to be defined.
Code: [Select]
`IActiveDesktop STRUC STDMETHOD QueryInterface, :REFIID, :ptr STDMETHOD AddRef STDMETHOD Release STDMETHOD ApplyChanges, :DWORD STDMETHOD GetWallpaper, :LPWSTR, :UINT, :DWORD STDMETHOD SetWallpaper, :LPCWSTR, :DWORD STDMETHOD GetWallpaperOptions, :LPWALLPAPEROPT, :DWORD STDMETHOD SetWallpaperOptions, :LPCWALLPAPEROPT, :DWORD STDMETHOD GetPattern, :LPWSTR, :UINT, :DWORD`

#### Vortex

• Member
• Posts: 2059
##### Re: Asmc source and binaries
« Reply #58 on: December 14, 2017, 05:55:11 AM »
Hi nidud,

Thanks for the info and for the update :t

#### nidud

• Member
• Posts: 1824
##### Re: Asmc source and binaries
« Reply #59 on: December 17, 2017, 12:47:43 AM »
Here's a PE COM-version using IShellFolder
Code: [Select]
`;; https://msdn.microsoft.com/en-us/library/windows/desktop/bb762114(v=vs.85).aspx;include windows.incinclude wininet.incinclude shlobj.incinclude shlwapi.incinclude stdio.incinclude tchar.inc.dataIID_IShellFolder  GUID _IID_IShellFolderifdef __PE__GUID_NULL GUID <0>IID_IOleDocument GUID _IID_IOleDocumentIID_IOleDocumentView GUID _IID_IOleDocumentViewIID_IOleDocumentSite GUID _IID_IOleDocumentSiteIID_IOleCommandTarget GUID _IID_IOleCommandTargetIID_IExplorerPaneVisibility GUID _IID_IExplorerPaneVisibilityIID_IBandHost GUID _IID_IBandHostIID_INameSpaceTreeControl GUID _IID_INameSpaceTreeControlIID_INewMenuClient GUID _IID_INewMenuClientIID_IEnumerableView GUID _IID_IEnumerableViewIID_IWebWizardExtension GUID _IID_IWebWizardExtensionIID_IWizardSite GUID _IID_IWizardSiteIID_IProfferService GUID _IID_IProfferServiceIID_ICommDlgBrowser GUID _IID_ICommDlgBrowserIID_IFolderView GUID _IID_IFolderViewIID_IShellTaskScheduler GUID _IID_IShellTaskSchedulerIID_IWebBrowserApp GUID _IID_IWebBrowserAppIID_IProtectFocus GUID _IID_IProtectFocusIID_IEnumOleDocumentViews GUID _IID_IEnumOleDocumentViewsendif.codemain proc  local psfParent:LPIShellFolder  local pidlRelative:ptr PCUITEMID_CHILD  local pidlItem:PIDLIST_ABSOLUTE  local szDisplayName[MAX_PATH]:TCHAR  local strret:STRRET    mov pidlItem,ILCreateFromPath("C:\\")    .ifd !SHBindToParent(pidlItem, &IID_IShellFolder, &psfParent, &pidlRelative) psfParent.GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strret) psfParent.Release() StrRetToBuf(&strret, pidlRelative, &szDisplayName, MAX_PATH) printf("%s\n", &szDisplayName)    .endif    ILFree(pidlItem)    xor eax,eax    retmain endp    end _tstart`