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

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #255 on: February 26, 2020, 07:06:38 AM »
mov  g_mem, procedure() fails if g_mem is an external variable.

This seems to work:

externdef g_mem:ptr
foo proto

    mov g_mem,&foo
    mov g_mem,foo()

Quote

mov  [rbx].MYSTRUCT.data.a, &[rbx].MYSTRUCT.data    ; This will fail

This failed on &[ but also on size > 8 (MYSTRUCT.data is 16). Fixed in version 2.31.18.

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #256 on: February 26, 2020, 07:23:53 AM »
Some notes about inline function and stack alignment.

So basically the stack always point to a @ReservedStack sized aligned memory block of at least 32 byte. In order to allocate more stack the reserved call-stack has to be relocated:

Added some macros to push registers and allocating memory.

Simple allocation:

st_alloc macro size
    lea  rax,[rsp + @ReservedStack - ( ( (size) + _GRANULARITY - 1 ) and -(_GRANULARITY) )]
    lea  rsp,[rax - @ReservedStack]
    retm <rax>
    endm

st_free macro size
    lea  rsp,[rsp + ( ( (size) + _GRANULARITY - 1 ) and -(_GRANULARITY) )]
    exitm<>
    endm

The call stack is at least 32 byte so 4 registers may be moved:

st_pushregs macro size
    mov  [rsp+@ReservedStack-0x08],rsi
    mov  [rsp+@ReservedStack-0x10],rdi
    mov  [rsp+@ReservedStack-0x18],rbx
    mov  [rsp+@ReservedStack-0x20],rcx
    lea  rsp,[rsp-32]
    ifnb <size>
        exitm<st_alloc(size)>
    endif
    exitm<>
    endm

st_popregs macro size
    ifnb <size>
        st_free(size)
    endif
    lea  rsp,[rsp+32]
    mov  rsi,[rsp+@ReservedStack-0x08]
    mov  rdi,[rsp+@ReservedStack-0x10]
    mov  rbx,[rsp+@ReservedStack-0x18]
    mov  rcx,[rsp+@ReservedStack-0x20]
    exitm<>
    endm

Pushing registers directly:

st_push macro regs:vararg
  local level
    lea rsp,[rsp+@ReservedStack]
    level = 0
    for reg,<regs>
        push reg
        level = level xor 1
        endm
    lea rsp,[rsp-@ReservedStack-level*8]
    exitm<>
    endm

st_pop macro regs:vararg
  local level
    level = 0
    for reg,<regs>
        level = level xor 1
        endm
    lea rsp,[rsp+@ReservedStack+level*8]
    for reg,<regs>
        pop reg
        endm
    lea rsp,[rsp-@ReservedStack]
    exitm<>
    endm

Greenhorn

  • Member
  • **
  • Posts: 126
Re: Asmc source and binaries
« Reply #257 on: February 28, 2020, 08:36:58 AM »
This seems to work:

externdef g_mem:ptr
foo proto

    mov g_mem,&foo
    mov g_mem,foo()


Hi nidud,

sorry that I wasn't enough precisely on this.

externdef g_nFontSize:      LONG

mov g_nFontSize, GetDlgItemInt (hwnd, IDC_SIZELIST, 0, 0)


Gives me: error A2022: instruction operands must be the same size : 4 - 8

Greenhorn

  • Member
  • **
  • Posts: 126
Re: Asmc source and binaries
« Reply #258 on: February 28, 2020, 08:53:03 AM »
The parser used for translating header files sort of evolved over time so newer files are more correctly translated. The commctrl.inc file is probably one of the first.

The result is assembled and errors corrected. Missing <> may end with data or code creation so this is tested but as for macros, there are around 6300 of them and only a few of these are tested so you still get a lot of these macros:

exitm<fn(hwnd, WM_GETDLGCODE, (lpmsg ? lpmsg->wParam : 0), (lpmsg))>

Quote
Using the TabCtrl_InsertItem or the SNDMSG macro will end up with error A2008: syntax error SendMessageW.
The macros are expanded to:
00000075                           SendMessageW, hwndTab, TCM_INSERTITEMW, 1, &tcitem

So from this using asmc64 -ws

include windows.inc
include commctrl.inc

    .code

WndProc proc hwnd:HWND, uiMsg:UINT, wParam:WPARAM, lParam:LPARAM

    TabCtrl_InsertItem(hwnd, 1, lParam)
    TabCtrl_InsertItem(hwnd, 1, &lParam)
    ret

WndProc endp

    end

I get this:

    * mov r9, lParam
    * mov r8d, 1
    * mov edx, TCM_INSERTITEM
    * mov rcx, hwnd
    * call SendMessageW
    * lea r9, lParam
    * mov r8d, 1
    * mov edx, TCM_INSERTITEM
    * mov rcx, hwnd
    * call SendMessageW


Hm, strange. I get the error:
test.asm(16) : error A2008: syntax error : SendMessageW
test.asm(17) : error A2008: syntax error : SendMessageW

Tested with your code and switch -ws (asmc 2.31.17).

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #259 on: February 28, 2020, 11:47:52 AM »
sorry that I wasn't enough precisely on this.

externdef g_nFontSize:      LONG

mov g_nFontSize, GetDlgItemInt (hwnd, IDC_SIZELIST, 0, 0)


Gives me: error A2022: instruction operands must be the same size : 4 - 8

I flipped LONG to PTR in the test so that works but failed with DWORD. This is fixed in v2.31.21.

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #260 on: February 28, 2020, 12:16:43 PM »
Hm, strange. I get the error:
test.asm(16) : error A2008: syntax error : SendMessageW
test.asm(17) : error A2008: syntax error : SendMessageW

Tested with your code and switch -ws (asmc 2.31.17).

Maybe the header files have been updated? I still don't get any errors so if only the -ws switch was used the only options must be the headers or the binary.

You may try creating a list file and see if you get some more information:
asmc64 -ws -Fl -Sg test.asm

Greenhorn

  • Member
  • **
  • Posts: 126
Re: Asmc source and binaries
« Reply #261 on: February 29, 2020, 06:27:42 AM »
Maybe the header files have been updated? I still don't get any errors so if only the -ws switch was used the only options must be the headers or the binary.

You may try creating a list file and see if you get some more information:
asmc64 -ws -Fl -Sg test.asm

The output to the listing file is posted in my first post (and in my last as well).

Using the TabCtrl_InsertItem or the SNDMSG macro will end up with error A2008: syntax error SendMessageW.
The macros are expanded to:
00000075                           SendMessageW, hwndTab, TCM_INSERTITEMW, 1, &tcitem
So, the brackets "()" are removed, the comma is set after SendMessageW but the invoke is missing before SendMessaageW. Therefore asmc throws the error.
I have tested it with asmc includes and my own includes with the same result.
It seems that asmc gets lost in translation at some point in the cascade SNDMSG to SendMessage to SendMessageW.

Using SendMessage instead of SNDMSG works as expected:

TabCtrl_InsertItem macro hwnd, iItem, pitem
   ;exitm<SNDMSG(hwnd, TCM_INSERTITEM, iItem, pitem)>
   exitm<SendMessage(hwnd, TCM_INSERTITEM, iItem, pitem)>
   endm


Expands to:
00000054                    *   invoke SendMessageW,  hwndTab, TCM_INSERTITEMW, 0,addr  tcitem
00000054  4C8D4DA8          *    lea r9, tcitem
00000058  4533C0            *    xor r8d, r8d
0000005B  BA3E130000        *    mov edx, TCM_INSERTITEMW
00000060  488B4DE0          *    mov rcx, hwndTab
00000064  E800000000        *    call SendMessageW
                                invoke SendMessageW (hwndTab, TCM_INSERTITEMW, 0, &tcitem)


Kind regards
Greenhorn

Greenhorn

  • Member
  • **
  • Posts: 126
Re: Asmc source and binaries
« Reply #262 on: February 29, 2020, 06:42:02 AM »
Here the related code of my original file:
ASM file:
   LoadString (g_hInstance, IDS_SEARCHTAB_FIND, &szBuffer, MAX_PATH)
   mov  tcitem.mask_, TCIF_TEXT
   mov  tcitem.pszText, &szBuffer
   TabCtrl_InsertItem(hwndTab, 0, &tcitem)


LST file:
00000024                    *   invoke LoadStringW,  g_hInstance, IDS_SEARCHTAB_FIND,addr  szBuffer, MAX_PATH
00000024                    *    mov r9d, MAX_PATH
0000002A                    *    lea r8, szBuffer
00000031                    *    mov edx, IDS_SEARCHTAB_FIND
00000036                    *    mov rcx, g_hInstance
0000003D                    *    call LoadStringW
                                invoke LoadStringW (g_hInstance, IDS_SEARCHTAB_FIND, &szBuffer, MAX_PATH)
00000042                           mov  tcitem.mask_, TCIF_TEXT
00000049                           mov  tcitem.pszText, &szBuffer
00000049                    *    lea rax,szBuffer
00000050                    *    mov tcitem.pszText,rax
00000054                           SendMessageW, hwndTab, TCM_INSERTITEMW, 0, &tcitem
                           PeaSearch.asm(118) : error A2008: syntax error : SendMessageW


That you cannot reproduce the error makes me scratch my head.  :sad:

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #263 on: February 29, 2020, 08:40:06 AM »
I've tested with version 2.31.17 and that works fine as well so it's not the include files or the binary. You tested the source I provided and got the same error so it's not your source.

The only thing left I could think of is the environment and command line options.

    echo %asmc%
    echo %include%

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #264 on: February 29, 2020, 08:49:47 AM »
You could try a clean batch build of the simplified test case. This should assemble without any errors provided the include files are intact.

SET ASMC=
SET INCLUDE=
asmc64 -I\asmc\include -ws test.asm
pause

Greenhorn

  • Member
  • **
  • Posts: 126
Re: Asmc source and binaries
« Reply #265 on: February 29, 2020, 10:03:31 PM »
Environment variable ASMC doesn't exist on my maschine.

test.asm:
       option win64:3
   option frame:auto
   option casemap:none

include windows.inc
include commctrl.inc

    .code

WndProc proc hwnd:HWND, uiMsg:UINT, wParam:WPARAM, lParam:LPARAM

    TabCtrl_InsertItem(hwnd, 1, lParam)
    TabCtrl_InsertItem(hwnd, 1, &lParam)
    ret
WndProc endp
    end


build.cmd:
@echo off
echo %asmc%
echo %include%

SET ASMC=
SET INCLUDE=
asmc64 -I"D:\asmc\include" -ws test.asm
pause


Output:
ECHO ist ausgeschaltet (OFF).
C:\WATCOM\H;C:\WATCOM\H\NT;C:\WATCOM\H\NT\DIRECTX;C:\WATCOM\H\NT\DDK;D:\asmc\inc
lude\
Asmc Macro Assembler (x64) Version 2.31.21
Copyright (C) The Asmc Contributors. All Rights Reserved.
Portions Copyright (C) 1984-2002 Sybase, Inc. All Rights Reserved.

 Assembling: test.asm
test.asm(16) : error A2008: syntax error : SendMessageW
test.asm(17) : error A2008: syntax error : SendMessageW
Drücken Sie eine beliebige Taste . . .

Greenhorn

  • Member
  • **
  • Posts: 126
Re: Asmc source and binaries
« Reply #266 on: February 29, 2020, 10:24:11 PM »
Can't believe it and don't know what to say ...

I use an include file with some macros, it's a modified version of japhet's WINASM.inc, and there is a definition of SNDMSG which is defined before all others.

;--- SNDMSG is mainly used in COMMCTRL.INC and WINDOWSX.INC
ifndef SNDMSG
SNDMSG   macro hwnd, message, wparam, lparam
   exitm <SendMessage, hwnd, message, wparam, lparam>
    endm
endif

This caused the error.

Sorry for wasting your time, nidud. I'm embarrassed that I've overlooked this.

Kind regards
Greenhorn

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #267 on: March 01, 2020, 12:15:52 AM »
No problem. I spent countless hours doing the same and it's often difficult to figure out.

I solve this by using the commander to set the environment.

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #268 on: March 01, 2020, 02:01:49 AM »
As for the macros I think most of them actually works. The inline PROTO/MACRO implementation sort out the arguments for a MACRO where that is needed, at least for 64-bit. Loading arguments right to left in INVOKE also enable shifting arguments to the right.

Example:

TabCtrl proto :HWND, :WPARAM, :LPARAM
TabCtrl macro hwnd, iItem, pitem
    exitm<SNDMSG(hwnd, TCM_INSERTITEM, iItem, pitem)>
    endm

The macro shifts the parameters to the right without thrashing any registers.

    SendMessageA(rcx, TCM_INSERTITEM, rdx, r8)
    * mov     r9, r8
    * mov     r8, rdx
    * mov     edx, 4871
    * call    SendMessageA

I tested most of the math functions in intrin.inc but only a selected few of the API macros. The scratch program by Raymond Chen uses some of these macros.

Environment variable ASMC doesn't exist on my maschine.

It's possible to set some default arguments this way so that may have been part of the problem.

Quote

    option win64:3
    option frame:auto
    option casemap:none


These options are set as default by using the include files.

nidud

  • Member
  • *****
  • Posts: 1999
    • https://github.com/nidud/asmc
Re: Asmc source and binaries
« Reply #269 on: May 04, 2020, 08:31:23 AM »
Added some updates to the gdiplus headers to test some of the classes. This involves a lot of argument passing where the inline functions use the same call stack. There where two issues in 64-bit FASCALL with stack arguments that fails.

foo proto :ptr, :ptr, :ptr, :ptr, :ptr, :real4

    foo(0,0,0,0,[rsp+8],xmm3)

The memory operand (first stack arg) defaults to 4 and the register to 16. The target size is now tested so xmm regs are allowed for real4 and real8.

Construction of classes may now be done directly providing there's a proto type defined:

    Rect(0, 0, 400, 200)

This may be assigned or used as argument to a function call.

gdiplus use their own heap to allocate objects so the GdiplusStartupInput class is static given it's initialized before GdiplusStartup() (that's always the case come to think of it so malloc() should probably be used there), but the following Bitmap is dynamically allocated.

    .case WM_CREATE

        .new token:ULONG_PTR
        .new StartupInfo:GdiplusStartupInput()

        GdiplusStartup(&token, &StartupInfo, 0)

        .new bitmap:ptr Bitmap()

        bitmap.FromFile("..\\image.png", FALSE)
        bitmap.GetHBITMAP(NULL, &hBitmap)
        bitmap.Release()

        GdiplusShutdown(token)
        .endc

Sample directory:
https://github.com/nidud/asmc/tree/master/source/test/gdiplus