Author Topic: Asmc source and binaries  (Read 4413 times)

nidud

  • Member
  • *****
  • Posts: 1408
    • https://github.com/nidud/asmc
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>|*].dll

Usage: SYSDLL <options> [<mask>]

 /def - create .def files
 /lib - create .lib files
 /inc - create .inc files

Example:
Code: [Select]
ifdef __PE__
    .x64
    .model flat, fastcall
endif
include inc\msvcrt.inc

    .code

main 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 msvcrt
SYSDLL /inc msvcrt

Assemble:
Code: [Select]
asmc /win64 test.asm

inc\msvcrt.inc(1010) : error A2034: must be in segment block
 inc\msvcrt.inc(1010): Included by
  test.asm(11): Main line code
inc\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 :vararg
exit proto :vararg
exp proto :vararg
expf proto :vararg
;fabs proto :vararg
fclose proto :vararg

Assemble and link:
Code: [Select]
asmc /win64 test.asm
linkw lib lib\msvcrt.lib file test.obj

Assemble and link:
Code: [Select]
asmc /pe /D__PE__ test.asm

nidud

  • Member
  • *****
  • Posts: 1408
    • https://github.com/nidud/asmc
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.inc
include winres.inc
ifdef _WIN64
option win64:3
APPNAME   equ <"Win64 ASM Event Example">
CLASSNAME equ <"Win64ASMEventClass">
else
rax equ <eax>
rbx equ <ebx>
rcx equ <ecx>
APPNAME   equ <"Win32 ASM Event Example">
CLASSNAME equ <"Win32ASMEventClass">
endif

IDM_START_THREAD    equ 1
IDM_STOP_THREAD     equ 2
IDM_EXIT            equ 3
IDR_MAINMENU        equ 30
WM_FINISH           equ WM_USER+100h

.data
EventStop   BOOL FALSE
hMenu       HANDLE ?
hwnd        HANDLE ?
hEventStart HANDLE ?
hThread     HANDLE ?
ThreadID    dd ?

.code

ThrdProc 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
    ret

ThrdProc endp

WndProc 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
    ret

WndProc endp

WinMain 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_MAINMENU
ifdef _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
    ret

WinMain endp

WinStart proc
    mov rbx,GetModuleHandle(0)
    ExitProcess(WinMain(rbx, 0, GetCommandLine(), SW_SHOWDEFAULT))
WinStart endp

RCBEGIN

    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
    MENUEND

RCEND

    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 files
1425 macros

nidud

  • Member
  • *****
  • Posts: 1408
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #47 on: October 27, 2017, 01:23:18 AM »
Some new updates.

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: 1408
    • https://github.com/nidud/asmc
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.asm
3651 ClockTicks: \asmc\bin\asmc.exe -q real_math.asm
6287 ClockTicks: \jwasm\jwasm.exe -q real_math.asm

Added code:
312832 - version 2.25
333312 - version 2.26

A few types are added in addition to ZMMWORD:
Code: [Select]
8 16 32 64 128 256 512

1 2 4 8 10 16 32 64

AL AX EAX RAX XMM0 YMM0 ZMM0

  REAL10

REAL4 REAL8 REAL16 YMMWORD ZMMWORD

BYTE WORD DWORD QWORD OWORD YWORD ZWORD

nidud

  • Member
  • *****
  • Posts: 1408
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #49 on: November 16, 2017, 10:29:27 AM »
Added public label::

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]
.code

public_label::

    nop
    ret

    end

Code: [Select]
; Mode: 64 bits
; Syntax: MASM/ML64
; Instruction set: 8086, x64

public public_label


_text   SEGMENT PARA 'CODE'                             ; section number 1

public_label PROC
        nop                                             ; 0000 _ 90
        ret                                             ; 0001 _ C3
public_label ENDP

_text   ENDS

Vortex

  • Member
  • *****
  • Posts: 1723
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.dll

sysdll.exe /def C:\WINDOWS\System32\msvcrt.dll

sysdll.exe /inc C:\WINDOWS\SysWOW64\msvcrt.dll

sysdll.exe /inc C:\WINDOWS\System32\msvcrt.dll

sysdll.exe /lib C:\WINDOWS\SysWOW64\msvcrt.dll

sysdll.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: 1408
    • https://github.com/nidud/asmc
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 msvcrt
EXPORTS
"_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: 1723
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: 1408
    • https://github.com/nidud/asmc
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.

Some additional changes to Asmc:

  • 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: 1408
    • https://github.com/nidud/asmc
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 this
include windows.inc
include tchar.inc

;; Every Direct3D application this
include d3d9.inc

.data
g_bContinue dd TRUE

.code


;; Besides the main function, there must be a message processing function
MsgProc 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
    ret

MsgProc endp

;; The entry point of a windows application is the WinMain function
WinMain 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
    ret

WinMain 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: 1408
    • https://github.com/nidud/asmc
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 this
include windows.inc
include tchar.inc

;; Every Direct3D application this
include d3d9.inc
include d3dx9.inc

.data
g_lpEffect  LPD3DXEFFECT NULL
g_lpVertexBuffer LPDIRECT3DVERTEXBUFFER9 NULL
g_ShaderMatrix D3DXMATRIX <>
g_bContinue dd TRUE


;;Definition of the Vertex Format including position and diffuse color
D3DFVF_COLOREDVERTEX equ (D3DFVF_XYZ or D3DFVF_DIFFUSE)

COLORED_VERTEX STRUC
x           FLOAT ?     ;; Position
y           FLOAT ?
z           FLOAT ?
color       dd ?        ;; Color
COLORED_VERTEX ENDS

.code


;; Besides the main function, there must be a message processing function
MsgProc 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
    ret

MsgProc endp

;; The entry point of a windows application is the WinMain function
WinMain 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
    ret

WinMain endp

    end _tstart

Vortex

  • Member
  • *****
  • Posts: 1723
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,stdcall
option casemap:none
option wstring:on

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\ole32.inc
include     SetWallpaper.inc

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\ole32.lib

; LPActDesk TYPEDEF PTR IActiveDesktop

.data

CLSID_IActiveDesktop    GUID sCLSID_IActiveDesktop
IID_IActiveDesktop      GUID sIID_IActiveDesktop

DesktopImg dw 'test.bmp',0

.data?

wpo         WALLPAPEROPT <>
pAD         dd ?

.code

start:

    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,0

END 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