The MASM Forum

64 bit assembler => UASM Assembler Development => Topic started by: hutch-- on July 21, 2019, 07:04:08 PM

Title: Quick play with UASM
Post by: hutch-- on July 21, 2019, 07:04:08 PM
Documentation is lousy by UASM seems to work OK. I could not find the reference for => OPTION PROC:NONE. I could not find a reason why it had to have "main" as its entry point. I just used an equate to get the name I wanted.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    option casemap:none

    includelib \masm32\lib64\kernel32.lib
    includelib \masm32\lib64\user32.lib

    MessageBoxA PROTO :QWORD,:QWORD,:QWORD,:QWORD
    MessageBox equ <MessageBoxA>
    ExitProcess PROTO :QWORD

    MB_OK equ <0>
    entry_point equ <main>

    .data
      caption db " The UASM Assembler", 0
      text    db "Bare Bones MessageBox", 0

    .code

    OPTION PROC:NONE

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 entry_point proc

    add rsp, 8

    invoke MessageBox,0,ADDR text,ADDR caption,MB_OK
    invoke ExitProcess,0

 entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

The build batch file.

@echo off

set appname=UASM1

del %appname%.obj
del %appname%.exe

\uasm\uasm64 -win64 %appname%.asm

\masm32\bin64\polink.exe /SUBSYSTEM:WINDOWS /entry:main /LARGEADDRESSAWARE %appname%.obj

dir %appname%.exe

pause
Title: Re: Quick play with UASM
Post by: TimoVJL on July 21, 2019, 08:05:02 PM
as link.exe and polink.exe understand those basic entry points mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup, why not use one of them ?
so only -subsystem is necessary for link.exe, but M$ must be a reason for that.
Title: Re: Quick play with UASM
Post by: hutch-- on July 21, 2019, 08:49:28 PM
If you don't need them, why use them. Assemblers do not need to assume C technology.
Title: Re: Quick play with UASM
Post by: TimoVJL on July 21, 2019, 08:59:02 PM
If you don't need them, why use them. Assemblers do not need to assume C technology.
You missed something, those don't depend of C
Even i know something about compilers, like C, it's a linker that i was talking about.
As i said, it's a M$ linker issue, not a C issue.

Your site, your rules, but try to be in truth :skrewy:
Title: Re: Quick play with UASM
Post by: hutch-- on July 21, 2019, 10:24:33 PM
 :biggrin:

mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup is not assembler technology, it is C technology. Assembler modules only need an entry point which you specify on the linker command line. I am not sure what you are trying to prove here.
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 01:40:44 AM
Here is a slightly tweaked version.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    option casemap:none

    includelib \masm32\lib64\kernel32.lib
    includelib \masm32\lib64\user32.lib

    MessageBoxA PROTO :QWORD,:QWORD,:QWORD,:QWORD
    MessageBox equ <MessageBoxA>
    ExitProcess PROTO :QWORD

    MB_OK equ <0>
    entry_point equ <main>
    NULL equ <0>

    t MACRO quoted
      LOCAL text
      LOCAL ptxt
      .data
        text db quoted,0
        ptxt dq text
      .code
      EXITM <ptxt>
    ENDM

    OPTION PROC:NONE

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

 entry_point proc

    sub rsp, 8

    invoke MessageBox,NULL,t("Bare Bones MessageBox"),t(" The UASM Assembler"),MB_OK
    invoke ExitProcess,0

 entry_point endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: Quick play with UASM
Post by: TimoVJL on July 22, 2019, 03:07:35 AM
As i said, a linker issue, predefined names in linker, not a C issue.
https://docs.microsoft.com/en-us/cpp/build/reference/entry-entry-point-symbol
Title: Re: Quick play with UASM
Post by: morgot on July 22, 2019, 03:56:17 AM
TimoVJL but why Masm32 don't need it? In masm I can write
.code
start:
...
nop
..
end start

Without any proc.
Title: Re: Quick play with UASM
Post by: felipe on July 22, 2019, 03:59:30 AM
From the link above (provided by timo):
Quote
It is recommended that you let the linker set the entry point so that the C run-time library is initialized correctly, and C++ constructors for static objects are executed.

By default, the starting address is a function name from the C run-time library. The linker selects it according to the attributes of the program, as shown in the following table.
Function name    Default for
mainCRTStartup (or wmainCRTStartup)    An application that uses /SUBSYSTEM:CONSOLE; calls main (or wmain)
WinMainCRTStartup (or wWinMainCRTStartup)    An application that uses /SUBSYSTEM:WINDOWS; calls WinMain (or wWinMain), which must be defined to use __stdcall
_DllMainCRTStartup    A DLL; calls DllMain if it exists, which must be defined to use __stdcall

Looks a lot like a c related issue...
Title: Re: Quick play with UASM
Post by: AW on July 22, 2019, 04:03:47 AM
Polink and Link.exe will accept any entry point  set in UASM with a correct syntax name, the same as in MASM. This includes the "entry_point" name. It will also accept labels as entry points but is not recommended for 64-bit when you want the OPTION for automatic stack alignment to work.
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 04:27:09 AM
Timo,

I am not sure what you are getting at, what have you missed with *****CRT***** = C runtime. Now I have no doubt that you can start an app with a C runtime procedure but the obvious is that an assembler does not need it.

I confess it seems like a waste of time posting a simple experiment with UASM as it ends up in yet another nonsense argument over very old technology from the Petzold era that aped a technique where a WinMain had 4 arguments which followed from the format of a 16 bit Win3.0 era code design and YES it was in C.

I was looking for some of the UASM folks who knew more of the reference material that I have yet to find. All I have so far is some old stuff from the data that Japheth wrote.
Title: Re: Quick play with UASM
Post by: TimoVJL on July 22, 2019, 04:34:37 AM
TimoVJL but why Masm32 don't need it? In masm I can write
.code
start:
...
nop
..
end start

Without any proc.
just look inside of .obj and find out why M$ link find that entry point, no magic.
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 04:48:50 AM
I knew I had stuff this old somewhere. This is how you ape a 16 bit Windows WinMain in early 32 bit.

start:
        invoke GetModuleHandle, NULL
        mov hInstance, eax

        invoke GetCommandLine
        mov CommandLine, eax

        invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
        invoke ExitProcess,eax

; #########################################################################

WinMain proc hInst     :DWORD,
             hPrevInst :DWORD,
             CmdLine   :DWORD,
             CmdShow   :DWORD

Most of it is redundant in Win32 and certainly in Win64. You do not need hPrevInst and CmdShow. It was just a pseudo compatibility with 16 bit Windows while updating to Win32.
Title: Re: Quick play with UASM
Post by: TimoVJL on July 22, 2019, 04:53:49 AM
Linker don't care about language, only symbol names,just  learn object file basics with wrj's PEView.exe.
It seems that i just waste my time here to teach some professionals to update their knowledge of some basic things.
I haven't been a professional programmer in my life, only a hobbyist, but some of my programs are still important part of production line in one factory.
My role was a IT support and a system expert person at that time.
I even created a C code to read Vertex Systems databases.


Title: Re: Quick play with UASM
Post by: felipe on July 22, 2019, 05:03:12 AM
It seems that i just waste my time here to teach some professionals to update their knowledge of some basic things.
I haven't been a professional programmer in my life, only a hobbyist, but some of my programs are still important part of production line in one factory.
My role was a IT support and a system expert person at that time.
I even created a C code to read Vertex Systems databases.


:biggrin: And you have never learned assembly language?
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 05:29:25 AM
Timo,

I think you have mixed up a couple of things, we all know that the entry point is set in the linker but the code for that entry point is in the source code that the assembler processes. Your original comment was a suggestion to use the CRT in the form mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup and I made you the comment that it is not needed in the source code of an assembler application.

Here is an example in another assembler, POASM.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    ExitProcess PROTO :QWORD
    MessageBoxA PROTO :QWORD,:QWORD,:QWORD,:QWORD

    MessageBox equ <MessageBoxA>
    MB_OK equ <0>

    includelib \masm32\lib64\kernel32.lib
    includelib \masm32\lib64\user32.lib

    .data
      msg db "A MessageBox in POASM",0
      ttl db " About",0

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 entry_point proc

    add rsp, 8

    invoke MessageBox,0,ADDR msg,ADDR ttl,MB_OK

    invoke ExitProcess,0

 entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

It is built with this batch file.

@echo off

set appname=app

if exist %appname%.obj del %appname%.obj
if exist %appname%.exe del %appname%.exe

\masm32\bin64\poasm.exe %appname%.asm

\masm32\bin64\polink.exe /SUBSYSTEM:WINDOWS /MACHINE:X64 /ENTRY:entry_point /nologo /LARGEADDRESSAWARE %appname%.obj

dir %appname%.*

pause
Title: Re: Quick play with UASM
Post by: AW on July 22, 2019, 05:49:14 AM
On one side people that has never used UASM in his life (but there is always a first time for everything) and on the other side people that has no clue at all about assembly language. Looks funny.  :skrewy:
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 05:55:43 AM
 :biggrin:

Yes you are right and with the amount of crap I have had to listen to in this topic I may not ever get there. Here is a tweaked version done in POASM. I am not really up to date with POASM but its has always been a decent tool

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    MessageBoxA PROTO :QWORD,:QWORD,:QWORD,:QWORD
    ExitProcess PROTO :QWORD

    MessageBox equ <MessageBoxA>
    MB_OK equ <0>

    includelib \masm32\lib64\kernel32.lib
    includelib \masm32\lib64\user32.lib

    t MACRO quoted
      LOCAL text
      LOCAL ptxt
      .data
        text db quoted,0
      .code
      EXITM <ADDR text>
    ENDM

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 entry_point proc

    sub rsp, 8

    invoke MessageBox,0,t("A MessageBox in POASM"),t(" About"),MB_OK

    invoke ExitProcess,0

 entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: Quick play with UASM
Post by: AW on July 22, 2019, 06:11:08 AM
Note that it will build as well with UASM without modification. However to run properly you will need to add OPTION PROC:NONE (it is indeed mentioned in the documentation) or alternatively OPTION PROLOGUE:NONE
Title: Re: Quick play with UASM
Post by: TimoVJL on July 22, 2019, 06:33:50 AM
Timo,

I think you have mixed up a couple of things, we all know that the entry point is set in the linker but the code for that entry point is in the source code that the assembler processes. Your original comment was a suggestion to use the CRT in the form mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup and I made you the comment that it is not needed in the source code of an assembler application.

Steve,
not me, you can read from Microsoft linker documents about those predefined symbols.

Title: Re: Quick play with UASM
Post by: TimoVJL on July 22, 2019, 06:58:57 AM
It seems that i just waste my time here to teach some professionals to update their knowledge of some basic things.
I haven't been a professional programmer in my life, only a hobbyist, but some of my programs are still important part of production line in one factory.
My role was a IT support and a system expert person at that time.
I even created a C code to read Vertex Systems databases.


:biggrin: And you have never learned assembly language?
a joke?
after over 10 years making bug report to software company of bug finding with WinDBG, what you except ?
i think it need more than just assembly language, you must understand a whole system around it.
Title: Re: Quick play with UASM
Post by: fearless on July 22, 2019, 08:00:05 AM
I was looking for some of the UASM folks who knew more of the reference material that I have yet to find. All I have so far is some old stuff from the data that Japheth wrote.
There is a pdf in the releases that contains the new stuff: uasm248_ext.pdf or similarly named.

The option for string literals is a nice handy feature

Code: [Select]
OPTION LITERALS:ONThen should be able to do this:
Code: [Select]
invoke MessageBox, NULL, "Bare Bones MessageBox", "The UASM Assembler", MB_OKInstead of using a macro - for convenience really, but could be useful

Code: [Select]
invoke MessageBox, NULL, t("Bare Bones MessageBox"), t("The UASM Assembler"), MB_OKIt also supports wide string literals when prefixed with L


The pdf manual does have a lot of interesting new features, lots to explore, and I'm sure they will be useful to many.
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 10:28:09 AM
fearless, Gratsie.  :thumbsup:
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 04:38:09 PM
I did try the option but got this result.

UASM v2.49, Jun 21 2019, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

UASM1.asm(44) : Error A2145: INVOKE argument type mismatch: argument 1
UASM1.asm(44) : Error A2145: INVOKE argument type mismatch: argument 2
UASM1.asm: 55 lines, 1 passes, 2 ms, 0 warnings, 2 errors
POLINK: fatal error: File not found: 'UASM1.obj'.
 Volume in drive K is disk3_k
 Volume Serial Number is 68C7-4DBB

 Directory of K:\uasm\test1

File Not Found
Press any key to continue . . .
Title: Re: Quick play with UASM
Post by: AW on July 22, 2019, 04:53:23 PM
@Hutch

> For a string literal to be accepted as such, the corresponding procedure parameter must be defined as PTR.
MessageBoxA PROTO :qword,:ptr,:ptr,:dword
Title: Re: Quick play with UASM
Post by: jj2007 on July 22, 2019, 05:43:38 PM
Right. That was introduced when somebody tried to pass "a" as the immediate value 97.
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 06:29:23 PM
Works perfect, Gratsie.
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 07:01:24 PM
I still have not got rid of the stack twiddle "sub rsp, 8". I have been scanning the PDF file but any FRAME attempt outputs an error.

In MASM I have automatic stack control so I can do this.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 entry_point proc

    rcall MessageBox,0,"A MessageBox in 64 bit MASM", \
                        "MASM Pure And Simple",MB_OK
    .exit

 entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: Quick play with UASM
Post by: fearless on July 22, 2019, 07:43:57 PM
try adding the following:

Code: [Select]
option win64 : 11
option frame : auto
option stackbase : rsp

and although I don't think it's required anymore (except for older versions of UASM) I put a FRAME keyword after the PROC (just for that backward compatibility)

Code: [Select]
entry_point proc frame
Title: Re: Quick play with UASM
Post by: hutch-- on July 22, 2019, 08:59:37 PM
Thanks, that worked well.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    OPTION CASEMAP:NONE
    OPTION LITERALS:ON
    OPTION FRAME:AUTO
    OPTION WIN64:11
    OPTION STACKBASE:RSP

    includelib \masm32\lib64\kernel32.lib
    includelib \masm32\lib64\user32.lib

    MessageBoxA PROTO :QWORD,:PTR,:PTR,:QWORD
    MessageBox equ <MessageBoxA>
    ExitProcess PROTO :QWORD

    close MACRO optvar:=<0>
      invoke ExitProcess,optvar
    ENDM

    MB_OK equ <0>
    NULL equ <0>

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 entry_point proc

    invoke MessageBox,NULL,"Bare Bones MessageBox"," The UASM Assembler",MB_OK

    close

 entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: Quick play with UASM
Post by: AW on July 22, 2019, 11:56:23 PM
The use of FRAME, which also exists in MASM, has never really been of interest to Assembly-Language-only programmers, although at a point in time everybody started using it with JWasm and successors, (including myself  :badgrin:). In addition, it was broken in its 64-bit version (Japeth heritage). After a lengthy discussion with Johnsa, which started probably here (http://masm32.com/board/index.php?topic=6617.0) and continued in private I believe that UASM ended with a functional FRAME for people that wants to use it. As a spin-off of that discussion I ended up doing an article for CodeProject (https://www.codeproject.com/Articles/1212332/bit-Structured-Exception-Handling-SEH-in-ASM) which is centered in MASM, but which applies to UASM as well (although I intend to update it and be more specific about its use with UASM).
Title: Re: Quick play with UASM
Post by: hutch-- on July 23, 2019, 12:20:57 AM
I went for a rat through my archives and found one of my own golden oldies, a template that I used for C code and it only has a "main" to start, no WinMain or CRT runtime module to start it. If you are old enough you will pick the K&R formatting. Its last build was with the VC 2003 toolkit.

/* ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« */

      #include <windows.h>

      LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

/* ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« */

void main()

    {
      HANDLE        hWnd;                       // local main window handle
      HICON         hIcon;                      // local icon handle
      LPMSG         pmsg;                       // pointer for MSG structure
      WNDCLASSEX *  pwc;                        // pointer to WNDCLASSEX structure
      MSG           msg;                        // local msg structure
      WNDCLASSEX    wc;                         // local structure for RegisterClassEx
      char          szTitle[]       = "Small C";
      char          szWindowClass[] = "SC_Class";

      /* ------------------------------------------
      Copy structure addresses to pointer variables
      ------------------------------------------ */
      pmsg = &msg;
      pwc  = &wc;

      hIcon = LoadIcon(NULL,IDI_APPLICATION);

      wc.cbSize           = sizeof(WNDCLASSEX);
      wc.style            = CS_BYTEALIGNWINDOW | CS_BYTEALIGNCLIENT;
      wc.lpfnWndProc      = (WNDPROC)WndProc;
      wc.cbClsExtra       = 0;
      wc.cbWndExtra       = 0;
      wc.hInstance        = (HINSTANCE)0x400000;
      wc.hIcon            = hIcon;
      wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
      wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
      wc.lpszMenuName     = NULL;
      wc.lpszClassName    = szWindowClass;
      wc.hIconSm          = hIcon;

      RegisterClassEx(pwc);     

      hWnd = CreateWindowEx(WS_EX_LEFT,
                            szWindowClass,
                            szTitle,
                            WS_OVERLAPPEDWINDOW,
                            CW_USEDEFAULT,0,
                            CW_USEDEFAULT,0,
                            NULL,NULL,(HINSTANCE)0x400000,NULL);

      ShowWindow(hWnd,SW_SHOW);
      UpdateWindow(hWnd);

      while (GetMessage(pmsg,NULL,0,0))
      {
        TranslateMessage(pmsg);
        DispatchMessage(pmsg);
      }

    }

/* ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« */

LRESULT CALLBACK WndProc(HWND hWin,UINT uMsg,
                         WPARAM wParam,LPARAM lParam)

    {
      switch (uMsg)
      {
        case WM_DESTROY:
        {
          PostQuitMessage(0);
          break;
        }
      }

    return DefWindowProc(hWin,uMsg,wParam,lParam);

    }

/* ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« */

Built with,

@echo off

set lib=h:\vctoolkit\lib\
set include=h:\vctoolkit\include\

if exist project2.exe del project2.exe
if exist project2.obj del project2.obj

h:\vctoolkit\bin\cl /c /G7 /O2 /Ot /GA /TC /W3 /FA project2.c
h:\vctoolkit\bin\Link /SUBSYSTEM:WINDOWS /entry:main /libpath:h:\msc6\lib @project2.rsp

dir project2.*

pause
Title: Re: Quick play with UASM
Post by: Vortex on July 23, 2019, 04:44:48 AM
Hi Hutch,

Same C example built with Manos' pcc32 compiler. The executable is 2560 bytes.
Title: Re: Quick play with UASM
Post by: AW on July 23, 2019, 05:16:39 AM
Let me see if I get this right (for a Windows program):
1) If you don't use the /Entry switch in the linker, the entry point for a Windows program will be WinMainCRTStartup.
For this case, on a ASM program you must have a procedure called WinMainCRTStartup.
On a C program WinMainCRTStartup is part of the runtime (it is possible to override it and save a few KBs), it runs first and then calls WinMain which is what you see on a normal C program.
2) If you use the /Entry switch, this will be called first either in ASM or in C. For an ASM program the Microsoft Linker will not even require you to specify /SUBSYSTEM:WINDOWS. If you don't specify /SUBSYSTEM:WINDOWS, the POLINK guy will tell you that it is assuming CONSOLE but that does not really matter, it will swallow whatever comes after the entry point.

So Hutch's old Windows application complies.  :biggrin:
Title: Re: Quick play with UASM
Post by: hutch-- on July 23, 2019, 09:21:11 AM
I have found a funny effect prototyping API functions for UASM so far.

Change this,
SendMessageA PROTO :QWORD,:QWORD,:QWORD,:QWORD
IFNDEF __UNICODE__
  SendMessage equ <SendMessageA>
ENDIF

To

SendMessageA PROTO :PTR,:PTR,:PTR,:PTR
IFNDEF __UNICODE__
  SendMessage equ <SendMessageA>
ENDIF

And it seems to work fine with the OPTION LITERALS:ON as well as any other 64 bit argumernt.




Title: Re: Quick play with UASM
Post by: TimoVJL on July 23, 2019, 08:33:08 PM
.drectve  section is useful for some linker options
Code: [Select]
OPTION DOTNAME
.drectve SEGMENT INFO
db '-subsystem:windows,5.2 -entry:start',0
.drectve ENDS
public start ; for ml64.exe
.code
start:
;WinMainCRTStartup proc
mov eax, 0
ret
;WinMainCRTStartup endp
end ;start ; ml64 don't accept entry point
Title: Re: Quick play with UASM
Post by: AW on July 23, 2019, 11:26:18 PM
Prototypes were invented to guide our hot little hands  :thumbsup:. We can do without them but is painful and will never be a recommended practice.

One size fits all prototyping has caused the need for new Masm SDK 64-bit include files. Microsoft had been alerting for decades that people should not rely on pointers being dwords. Nobody listened.
Title: Re: Quick play with UASM
Post by: hutch-- on July 23, 2019, 11:46:34 PM
 :biggrin:

I guess it depends on if the programmer knows what the pointer size is for the OS being used. DOS was 16 bit, win32 was 32 bit and win64 is 64 bit. If a programmer does not know this, they should stick to server side scripting.

UASM seems to work well once you can get it up and going, full window app comes easy, about the only real complaint after using 64 bit MASM is all the hassle producing fixed prototypes, something I left behind in 32 bit. It could do with the OPTION DOTNAME as this solves many naming problems, the need to specify PTR for literal text is a pest and the work around was to make all include file data types PTR instead of QWORD which is nonsensical but it works OK. This needs to be ditched and leave open the base datatype, not some notion of strong typing.
Title: Re: Quick play with UASM
Post by: Vortex on July 24, 2019, 05:10:46 AM
Example built with MS VC Toolkit 2003 :

Code: [Select]
#include <stdio.h>

void __stdcall ExitProcess(unsigned int uExitCode);

__declspec(naked) void proc()
{
 static char name[32];
 
 printf("What's your name?\n");
 scanf("%s",name);
 
 printf("Nice to meet you %s\n",name);
 
 ExitProcess(0);
}

Code: [Select]
Set vc2003=C:\MSVCTK2003

Set PATH=%vc2003%\bin;%PATH%
Set INCLUDE=%vc2003%\include;%INCLUDE%
Set LIB=%vc2003%\lib;%LIB%

cl /c /Zl Project.c
link /SUBSYSTEM:CONSOLE /ENTRY:proc Project.obj kernel32.lib H:\masm32\lib\msvcrt.lib
Title: Re: Quick play with UASM
Post by: TimoVJL on July 24, 2019, 05:50:11 AM
as msvcrt.dll was used, exit() is usable too.
Code: [Select]
void __cdecl mainCRTStartup(void) {exit(main());}
Title: Re: Quick play with UASM
Post by: hutch-- on July 24, 2019, 12:48:10 PM
A UASM window with no Microsoft components used in its build.

UASM assembler
POLINK linker
PORC resource compiler

The source is attached but it cannot be directly built as it assumes bits and pieces from all over my DEV drive but the exe runs correctly, it has an icon, manifest and version control block.
The "sauce".

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \uasm\include\uasm64rt.inc

    button  PROTO :PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR
    iMsgbox PROTO :PTR,:PTR,:PTR,:PTR,:PTR

    .data?
      hInstance dq ?
      hWnd      dq ?
      hIcon     dq ?
      hCursor   dq ?
      sWid      dq ?
      sHgt      dq ?
      hBrush    dq ?
      butn1     dq ?
      butn2     dq ?

    .data
      classname db "template_class",0
      caption db "UASM Template",0

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 entry_point proc

    mov hInstance, rv(GetModuleHandle,0)
    mov hIcon,     rv(LoadIcon,hInstance,10)
    mov hCursor,   rv(LoadCursor,0,IDC_ARROW)
    mov sWid,      rv(GetSystemMetrics,SM_CXSCREEN)
    mov sHgt,      rv(GetSystemMetrics,SM_CYSCREEN)
    mov hBrush,    rv(CreateSolidBrush,00666666h)

    call main

    close

 entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 main proc

    LOCAL wc      :WNDCLASSEX
    LOCAL lft     :QWORD
    LOCAL top     :QWORD
    LOCAL wid     :QWORD
    LOCAL hgt     :QWORD

    mov wc.cbSize,         SIZEOF WNDCLASSEX
    mov wc.style,          CS_BYTEALIGNCLIENT or CS_BYTEALIGNWINDOW
    mov wc.lpfnWndProc,    ptr$(WndProc)
    mov wc.cbClsExtra,     0
    mov wc.cbWndExtra,     0
    mrm wc.hInstance,      hInstance
    mrm wc.hIcon,          hIcon
    mrm wc.hCursor,        hCursor
    mrm wc.hbrBackground,  hBrush
    mov wc.lpszMenuName,   0
    mov wc.lpszClassName,  ptr$(classname)
    mrm wc.hIconSm,        hIcon

    invoke RegisterClassEx,ADDR wc

    mov wid, 800
    mov hgt, 450

    mov rax, sWid                           ; calculate offset from left side
    sub rax, wid
    shr rax, 1
    mov lft, rax

    mov rax, sHgt                           ; calculate offset from top edge
    sub rax, hgt
    shr rax, 1
    mov top, rax

    invoke CreateWindowEx,WS_EX_LEFT or WS_EX_ACCEPTFILES, \
                          ADDR classname,ADDR caption, \
                          WS_OVERLAPPEDWINDOW or WS_VISIBLE,\
                          lft,top,wid,hgt,0,0,hInstance,0
    mov hWnd, rax
    call msgloop
    ret

 main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

msgloop proc

    LOCAL msg    :MSG
    LOCAL pmsg   :QWORD

    mov pmsg, ptr$(msg)                     ; get the msg structure address
    jmp gmsg                                ; jump directly to GetMessage()

  mloop:
    invoke TranslateMessage,pmsg
    invoke DispatchMessage,pmsg
  gmsg:
    test rax, rv(GetMessage,pmsg,0,0,0)     ; loop until GetMessage returns zero
    jnz mloop

    ret

msgloop endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 WndProc proc hWin:PTR,uMsg:PTR,wParam:PTR,lParam:PTR

    .if uMsg == WM_COMMAND
      .if wParam == 100
        invoke iMsgbox,hWin,"Button 1 was pressed","Information",MB_OK,10
      .elseif wParam == 200
        jmp bye
      .elseif wParam == 300
        Invoke iMsgbox,hWin,"UASM 64 Bit Template","About",MB_OK,10
      .endif

    .elseif uMsg == WM_CREATE
      invoke LoadMenu,hInstance,100
      invoke SetMenu,hWin,rax
      mov butn1, rv(button,hInstance,hWin,"Button 1",50,40,100,20,100)
      mov butn2, rv(button,hInstance,hWin,"Close",50,65,100,20,200)
      xor rax, rax
      ret

    .elseif uMsg == WM_CLOSE
      bye:
      invoke SendMessage,hWin,WM_DESTROY,0,0

    .elseif uMsg == WM_DESTROY
      invoke PostQuitMessage,NULL

    .endif

    invoke DefWindowProc,hWin,uMsg,wParam,lParam

    ret

WndProc endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

button proc instance:PTR,hparent:PTR,text:PTR,topx:PTR,topy:PTR,wid:PTR,hgt:PTR,idnum:PTR

    invoke CreateWindowEx,0,"BUTTON",text, \
                          WS_CHILD or WS_VISIBLE,\
                          topx,topy,wid,hgt,hparent,idnum,instance,0
    ret

button endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 iMsgbox proc hParent:PTR,pText:PTR,pTitle:PTR,mbStyle:PTR,IconID:PTR

    LOCAL mbp   :MSGBOXPARAMSxx

    or mbStyle, MB_USERICON

    mov mbp.cbSize,             SIZEOF mbp
    mrm mbp.hwndOwner,          hParent
    mov mbp.hInstance,          rv(GetModuleHandle,0)
    mrm mbp.lpszText,           pText
    mrm mbp.lpszCaption,        pTitle
    mov rax, mbStyle
    mov mbp.dwStyle,            eax
    mrm mbp.lpszIcon,           IconID
    mov mbp.dwContextHelpId,    NULL
    mov mbp.lpfnMsgBoxCallback, NULL
    mov mbp.dwLanguageId,       NULL

    invoke MessageBoxIndirect,ADDR mbp

    ret

 iMsgbox endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: Quick play with UASM
Post by: jj2007 on July 24, 2019, 04:09:02 PM
Code: [Select]
button proc instance:PTR,hparent:PTR,text:PTR,topx:PTR,topy:PTR,wid:PTR,hgt:PTR,idnum:PTRWe all know how params are being passed in x64: rcx, rdx, r8, r9, then QWORDs on the stack. The receiving end will pick what it needs, mostly DWORDs in this case. So technically speaking, you can cheat the assembler in x64, passing only "pointers". But is it wise to do so?
Title: Re: Quick play with UASM
Post by: hutch-- on July 24, 2019, 04:50:34 PM
 :biggrin:

> But is it wise to do so?

No its not as it makes a fool of the pseudo strong typing. The alternative is to spend YEARS manually editing prototypes which no-one is willing to do. Auto formatting prototypes based on the actual data size is viable as a vast number of API functions use 64 bit arguments and even if they don't, the stack layout is done in 64 bit slots.

I would look for an option to turn it off while still being able to use the literal strings in invoke calls.
Title: Re: Quick play with UASM
Post by: jj2007 on July 24, 2019, 05:46:31 PM
If you would abandon for a moment your ideological "hot little hands" position, you might reflect on mechanisms to extract the size from C headers. I had started such an exercise, it took me a few days to get it 90% right, but then I completely lost interest in 64-bit coding and abandoned the project. I could dig it out, but of course, it's MasmBasic.
Title: Re: Quick play with UASM
Post by: LiaoMi on July 24, 2019, 06:02:23 PM
Code: [Select]
button proc instance:PTR,hparent:PTR,text:PTR,topx:PTR,topy:PTR,wid:PTR,hgt:PTR,idnum:PTRWe all know how params are being passed in x64: rcx, rdx, r8, r9, then QWORDs on the stack. The receiving end will pick what it needs, mostly DWORDs in this case. So technically speaking, you can cheat the assembler in x64, passing only "pointers". But is it wise to do so?

Hi jj2007,

Full SDK 10.0 translate for 64 and 32 bits - http://masm32.com/board/index.php?topic=563.0 (http://masm32.com/board/index.php?topic=563.0) - uses this PTR technique, on the forum it is discussed in the section of this sdk. I use it from 2016, during this time there were no problems.

I was unable to setup your SDK for use on my computer :(
I am curious if anybody else except you succeeded to set it up
I think that it requires to much work and I am wondering how someone new in programming can use it
I will stick to WinInc, it is simple to use and runs without flow :t
Why use XMASM
It is more clear like this in WinInc:
Code: [Select]
@DefProto WINOLEAPI, OleCreate, stdcall, ,<:REFCLSID,:REFIID,:DWORD,:LPFORMATETC,:LPOLECLIENTSITE,:LPSTORAGE,:ptr LPVOID>, 28
than this in SDK:
Code: [Select]
OleCreate PROTO :DWORD ,:DWORD ,:DWORD ,:XMASM ,:XMASM ,:XMASM ,:XMASM

XMASM = PTR
Title: Re: Quick play with UASM
Post by: johnsa on July 24, 2019, 06:43:50 PM
You can use regular :DWORD, :QWORD etc wherever you want on the prototypes.. the :PTR notation was purely to prevent conflicts between using an actual string literal and numeric constant string.

literalStringProc PROTO :PTR
constantProc PROTO :DWORD

invoke literalStringProc, "abcd"
invoke constantProc, "abcd"

What might be an option as I wouldn't want to remove this safety mechanism (we didn't have it originally and were bitten with unexpected results - bugs)
We "could" have an OPTION UNSAFE STRING or something like that, which would then lift the :PTR requirement... but then any use of INVOKE "...." would assume you meant a string literal and never a string constant -> number conversion
Title: Re: Quick play with UASM
Post by: hutch-- on July 24, 2019, 06:47:30 PM
jj,

Have a look at this pile of crap.

WINBASEAPI
BOOL
WINAPI
InitOnceExecuteOnce (
    __inout PINIT_ONCE InitOnce,
    __in __callback PINIT_ONCE_FN InitFn,
    __inout_opt PVOID Parameter,
    __deref_opt_out_opt LPVOID *Context
    );

I have cut this out manually but look at what you need to be able to identify the prototype. There are 3 equates that may be defined in the header file but may also be defined in another header file. Then for each argument you have a number of other externally defined equates as qualifying directives for the argument. You can determine the actual argument by it being followed by a trailing comma and you can determine the end of the prototype by the ";" character.

Then you have to track back to find the size of the qualifying directives and apply them to the arguments and again the equates for the qualifying directive may not be in the same H file.

There is in fact a trick to avoid most of this crap, load only the H file into CL and send the output to STDOUT and when redirected to a file you get most of the crap removed.
Title: Re: Quick play with UASM
Post by: hutch-- on July 24, 2019, 06:51:26 PM
John,

Its the prototypes where its a problem, when you have large counts of API functions, without being able to automate the arguments, you are stuck with manually editing a massive number of prototypes which could take years to do. Defining all args as PTR works but its a crude way to get around this limitation.
Title: Re: Quick play with UASM
Post by: johnsa on July 24, 2019, 06:57:20 PM
Just had another idea... to prevent a conflict.. we could force the use of a different delimiter for literal strings.. so instead of " " in the invoke, perhaps ` ` ? like newer HLL template string literals.
Title: Re: Quick play with UASM
Post by: hutch-- on July 24, 2019, 07:18:44 PM
I am used to that with alternate quotes in MASM but an OFF switch would be a better choice as double quotes are the normal notation across a large number of programming languages. If you can do large numbers of prototypes using the native QWORD, it makes include file a lot easier to generate. Having the option to use the alternate equates for assembler data types is easy enough to do for people who like that format.
Title: Re: Quick play with UASM
Post by: johnsa on July 24, 2019, 08:25:07 PM
I'll have a think more about it, as long as whatever we do prevents ambiguity between "abcd"(CONSTANT NUMERIC) and "abcd"(STRING)
Title: Re: Quick play with UASM
Post by: AW on July 24, 2019, 09:46:02 PM
On the function declarations theme, Microsoft never bothered to make life (relatively) easy for languages other than C/C++ (even for C#, everybody knows the complicative mess that is that Pinvoke thingy, and there are no ready-made include files).
I am remembering the Vulkan Registry (https://github.com/KhronosGroup/Vulkan-Docs/blob/master/xml/vk.xml), which is a long tabular XML document containing, within other things, every detail about each function and data type and has been used by other languages to produce Vulkan bindings with relative easiness.
Microsoft has never done anything similar because does not want.

Title: Re: Quick play with UASM
Post by: hutch-- on July 24, 2019, 10:21:33 PM
John,

The way I did it in the macros for 64 bit masm was to scan the source that could either be a string literal or a string address for a leading double quote, if it is a double quote, it reads the quoted text into a data section ID and returns its address. This way you can handle both literal strings and string addresses in the same location.

invoke MessageBox,hWin,pMsg,"About",MB_OK

This would not be uncommon if the text body was too large to easily fit on a line of code so being able to handle both is a lot more flexible.
Title: Re: Quick play with UASM
Post by: nidud on July 24, 2019, 11:34:50 PM
I went a few rounds (http://masm32.com/board/index.php?topic=902.msg48815#msg48815) with this issue when added to Asmc. The conclusion was (http://masm32.com/board/index.php?topic=902.msg50161#msg50161) not to expand any strings except within a proc(""). Later some exceptions was made for handle Unicode strings (http://masm32.com/board/index.php?topic=5942.msg64618#msg64618).

The arguments for this approach is a clear break from Masm syntax which is difficult to handle without this.

    MessageBox(hWin, pMsg, "About", MB_OK)
Title: Re: Quick play with UASM
Post by: hutch-- on July 24, 2019, 11:51:29 PM
How do you do the return value ? All I do in MASM is use the function form and return RAX.

mov var, rv(MessageBox,hWin,"Text Message","Title",MB_OK)
Title: Re: Quick play with UASM
Post by: nidud on July 25, 2019, 12:08:58 AM
By probing the size and type (https://github.com/nidud/asmc/blob/master/source/asmc/src/X86/hll.asm#L1111) of var.

foo proto

    .code

main proc

  local p:ptr, x:real8

    mov     al,foo()
    mov     p,foo()
    movsd   x,foo()
    ret

main endp

    end
        push    rbp
        mov     rbp, rsp
        sub     rsp, 48
        call    foo   
        mov     al, al
        call    foo   
        mov     qword ptr [rbp-8H], rax
        call    foo                     
        movsd   qword ptr [rbp-10H], xmm0
        leave                           
        ret                             
Title: Re: Quick play with UASM
Post by: johnsa on July 25, 2019, 12:10:23 AM
hutch, the problem isn't string literal vs string pointer .. internally that amounts to the same thing.. it's when you want the string literal "abcd" to actually mean the number "60616263h" or whatever the ascii code is off hand :)

We've done a similar thing in uasm with the hll style calls and return types, the default is eax or rax unless you specify the return type explicitly on the PROTO. That way it can type check that the returned type fits into the register/variable you're putting it into.
Title: Re: Quick play with UASM
Post by: hutch-- on July 25, 2019, 02:10:58 AM
John,

I probably have a touch of barbarian here but an assembler is a basic tool that lets you do things that really do not work and makes a mess of your app. Go down the path of hand holding and its a never ending disaster, it is really up to the user to know the difference between a number 1234 and 4 characters in quotes "1234". If a user makes a blunder like this, an error message should be what they get from making a mistake.

One of the things I like about 64 bit MASM is its crudity, it is one of the most terse tools I have ever used but you find mistakes (bugz) real fast when it crashes around your ears. You have the advantage of writing an assembler that can take the very rough edges off assembler programming but if you go the path of hand holding, you make your own cross very heavy to carry.

The rough distinction I am suggesting is to be able to turn off the requirement of type casting for string literals as it makes the include files much simpler and thus a lot easier to make reliable from the really messy Microsoft header files.
Title: Re: Quick play with UASM
Post by: jj2007 on July 25, 2019, 02:29:14 AM
John,

My 2cts: Please leave it "as is", i.e. do the conversion to a string only if the routine explicitly asks for a pointer; that's what PROTO is good for. No coder will pass the immediate value "abcd" knowing that the routine needs a pointer - it must be chr$("abcd"), not "abcd" alias 64636261h.
Title: Re: Quick play with UASM
Post by: johnsa on July 25, 2019, 02:32:30 AM
It's not quite that simple unfortunately, the problem is the parser side of things.

It encounters INVOKE SOMEPROC , "ABCD"

Now, what does it do with "ABCD" ? In MASM, old JWASM etc that is simply converted to a numeric representation, if you tried more than 4 chars you'd get an error that the numeric value is too large, fair enough.
Now with string literals, if they're enabled.. what is that.. is it a 4 character string, which must be put in .const/.data and referenced with a pointer (like CSTR("") would) or must the immediate value be given.

That is where the ambiguity lies. It's easy enough to not require the argument type to be :PTR, but then that excludes one or the other ability. If we assume they are always string literals than you can never use "ABCD" as an immediate, which breaks existing code. Alternatively if we assume that they are always immediates, then you can't convert it to a literal. Either string literals must use a different delimiter other than " " or we have to use the argument type from the proto to clearly indicate the desired intention.

There is nothing stopping conversion/use of headers with basic types :DWORD, :QWORD etc it just means you can't use them as-is with string literals unless you modify them, wrap them or rely on an existing macro solution like CSTR.

JJ I agree, that was why this decision was taken.. it ensures that if and when you use a string literal in uasm, you have thought about the implication and the proto argument matches the intention of being a ptr.
Title: Re: Quick play with UASM
Post by: AW on July 25, 2019, 02:47:34 AM
I understand both parts arguments, however it appears that once we select OPTION LITERALS:ON anything enclosed between quotes will be considered a string, even if we don't have a PTR parameter, until we use OPTION LITERALS:OFF, as we do in the code below.
proc2 expects a qword but if we don't deactivate OPTION LITERALS:ON with OPTION LITERALS:OFF    it will not even build.

Code: [Select]
option win64 : 11

includelib \masm32\lib64\kernel32.lib
includelib \masm32\lib64\user32.lib

MessageBoxA PROTO :QWORD,:PTR,:PTR,:DWORD
MessageBox equ <MessageBoxA>
ExitProcess PROTO :DWORD
proc2 proto :qword

.code

proc2 proc myValue : qword
ret
proc2 endp

main proc

OPTION LITERALS:ON
invoke MessageBox, 0, "Hello World", "Title", 0
OPTION LITERALS:OFF
invoke proc2, "abcd"
invoke ExitProcess,0
main endp

end

COMMENT ?
0007ff7`48d31006 33c9            xor     ecx,ecx
00007ff7`48d31008 488d15f11f0000  lea     rdx,[test6+0x3000 (00007ff7`48d33000)]
00007ff7`48d3100f 4c8d05f61f0000  lea     r8,[test6+0x300c (00007ff7`48d3300c)]
00007ff7`48d31016 4533c9          xor     r9d,r9d
00007ff7`48d31019 e819000000      call    test6+0x1037 (00007ff7`48d31037)
00007ff7`48d3101e 48c7c164636261  mov     rcx,61626364h
00007ff7`48d31025 e8d6ffffff      call    test6+0x1000 (00007ff7`48d31000)
00007ff7`48d3102a 33c9            xor     ecx,ecx
00007ff7`48d3102c e800000000      call    test6+0x1031 (00007ff7`48d31031)

?
Title: Re: Quick play with UASM
Post by: hutch-- on July 25, 2019, 03:44:23 AM
This is what has me tossed, in MASM 64 bit with macros, I either get quoted text OR you put a number there, that can be an immediate or a variable and it is easy enough to parse, if the argument starts with a double quote, its a string, if its a number, its an immediate. If it can be done in the pre-processor in MASM it should not be a big deal when you are writing an assembler.

Now I have a work around, make all of the prototypes PTR and the string literals work and everything else is passed as a PTR in 64 bit Windows is 64 bit. Its just that its very untidy and misleading. If someone types "abcd" then it should generate an error.
Title: Re: Quick play with UASM
Post by: johnsa on July 25, 2019, 06:13:15 AM

Personally.. I would agree that using "abcd" as a numeric expectation/value isn't great in the first place.. but that's how MASM works and there is code out there expecting it to be that way.

I guess it has "a" place (pardon the quoted pun) :)

for example,

CompareDwordAsASCII PROC bufferPtr:PTR, dwordStringValue:DWORD
mov rdi,bufferPtr
mov eax,dwordStringValue
cmp [rdi],eax
....

and you'd call it with:
CompareDwordAsASCII ADDR myBuffer, "heap"

I imagine that most legacy uses are of this sort of style for 1/2/4 char strings.

Title: Re: Quick play with UASM
Post by: johnsa on July 25, 2019, 06:16:52 AM
AW that sounds like a bug to me in that case, the string should work as a literal string for message box and as a qword with value "abcd" after that.. i'll check that one.
Title: Re: Quick play with UASM
Post by: hutch-- on July 25, 2019, 10:55:00 AM
I think I get what the problem John addressed happens to be. It is common to write mnemonics where you use quoted text for characters.

    cmp eax, "x"    ; and all other data sizes. "xx","xxxx","xxxxxxxx"

This is normal mnemonic coding practice but use it in a function call and it is ambiguous. It can be either quoted text "My Text" or a number "abcd". Rather than inflicting a form of strong typing to stop people from making an error, test if its a valid number "abcde" and generate an error if its not. It is just that quote text is just about universal across programming languages where quoted numbers "1234" are not.

If someone wants to put "abcd" in a function call, they are writing text "abcd". I would suggest that a data type "PTR" should only ever be an equate to the actual pointer size.

    PTR equ <QWORD>  ; in 64 bit
Title: Re: Quick play with UASM
Post by: AW on July 25, 2019, 03:21:37 PM
In Visual Studio C/C++, GCC, and others, we can pass multi-character constants within single-quotes. These are called multi-character literals and have type int (i,e 4 bytes). This behavior is considered implementation-defined, i.e, not part of the C/C++ standards.
For example, what C++14 (C is similar) says is:
"
An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacter literal, or an ordinary character literal containing a single c-char not representable in the execution character set, is conditionally-supported, has type int, and has an implementation-defined value.
"
One conclusion we can take now is that the standards do not consider qword size (8 bytes) multi-character constants, they are limited to int (4 bytes).
Although is not absurd in Assembly Language to consider qword size multi-character constants, they are not a current practice. However, even if UASM restricts multi-character constants to dword size this will not make happy people that do not use prototypes, or consider them a girly thing - so, is a no-solution. In addition, for ASM is also a no solution to use single quotes specifically for that, since single quotes are an alternative to double quotes. I don't think the grave accent is an excellent solution, but is not bad at all, because not all keyboards have it (but people can always type ALT 96).

An example C implementation:

Code: [Select]
#include <stdlib.h>
#include <stdio.h>

void myFunction1(char *str)
{
printf("%s\n", str);
return;
}

void myFunction2(unsigned int myValue)
{
printf("0x%x\n", myValue);
return;
}

int main()
{
myFunction1("abcd");
myFunction2('abcd');
return 0;
}

Output:
abcd
0x61626364
Title: Re: Quick play with UASM
Post by: hutch-- on July 25, 2019, 05:17:11 PM
I can do this in MASM easily.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

 entry_point proc

    mov rax, "abcdefgh"                 ; load immediate into register

    conout "abcdefgh = ",str$(rax),lf   ; display immediate src string + numeric result

    waitkey
    .exit

 entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end


Screen output,
abcdefgh = 7017280452245743464
Press any key to continue...
Title: Re: Quick play with UASM
Post by: AW on July 25, 2019, 05:47:35 PM
I know it required, and still requires, a lot of effort to produce brilliant macros to compensate for the MASM lack of features and shortcomings.
Macros will always have a significant place in all assemblers, whether they are called macro assemblers or not. Actually I never met an assembler that does not do macros and some have a much larger macro grammar than MASM.

This does not mean that we need to make a holy war against more advanced assemblers than MASM is, simply because they prefer to use internal code to replace some hand crafted macros. In my opinion - the perspective of a single user - the code becomes more clean when we don't abuse macros.