News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Should we improve the Masm64 SDK?

Started by jj2007, September 05, 2023, 08:05:25 PM

Previous topic - Next topic

jj2007

Following a comment from NoCforMe, I had a look at an old friend, StdOut:

StdOut proc lpszText:DWORD

    LOCAL hOutPut  :DWORD
    LOCAL bWritten :DWORD
    LOCAL sl      :DWORD

    invoke GetStdHandle,STD_OUTPUT_HANDLE
    mov hOutPut, eax

    invoke StrLen,lpszText
    mov sl, eax

    invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL

    mov eax, bWritten
    ret

StdOut endp

So I felt tempted to polish it a little bit, and here are two new versions:

include \masm32\include\masm32rt.inc ; purest Masm32 SDK code
include CodeSize.inc
.code
StdOut_s:
StdOut proc lpszText:DWORD

    LOCAL hOutPut  :DWORD
    LOCAL bWritten :DWORD
    LOCAL sl      :DWORD

    invoke GetStdHandle,STD_OUTPUT_HANDLE
    mov hOutPut, eax

    invoke StrLen,lpszText
    mov sl, eax

    invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL

    mov eax, bWritten
    ret

StdOut endp
StdOut_endp:
StdOutNew_s:
StdOutNew proc lpszText:DWORD
    LOCAL bWritten :DWORD
    push NULL
    lea eax, bWritten
    push eax
    push rv(StrLen, lpszText)
    push lpszText
    push rv(GetStdHandle, STD_OUTPUT_HANDLE)
    call WriteFile ; invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL
    ; mov eax, bWritten ; masmlib.chm: "There is no return value" (not sure if it has ever been used by an insider)
    ret
StdOutNew endp
StdOutNew_endp:

StdOutExtreme_s:
StdOutExtreme proc lpszText:DWORD
    push NULL
    push esp ; we assume that WriteFile writes to lpOverlapped when it's finished
    push rv(StrLen, lpszText)
    push lpszText
    push rv(GetStdHandle, STD_OUTPUT_HANDLE)
    call WriteFile ; invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL
    ret
StdOutExtreme endp
StdOutExtreme_endp:

start:
  cls
  invoke StdOut, chr$("Hello World StdOut", 13, 10)   ; print "Hello World" without using the print macro
  invoke StdOutNew, chr$("Hello World StdOutNew", 13, 10)   ; same but with modified library routine
  invoke StdOutExtreme, chr$("Hello World StdOutExtreme", 13, 10)   ; same but with dirty tricks
  CodeSize StdOut
  CodeSize StdOutNew
  CodeSize StdOutExtreme
  exit

end start

Output:
Hello World StdOut
Hello World StdOutNew
Hello World StdOutExtreme
56 bytes for StdOut
43 bytes for StdOutNew
35 bytes for StdOutExtreme

StdOutNew is 23% shorter, and certainly not slower.
StdOutExtreme is 37% shorter, not slower but it's a hack (it will always work, though).

Now the question: if we examine the Masm64 SDK, which has been developed by Hutch in a hurry, and find things that could be improved, should we change it, yes or no?

Some will argue, of course, that Hutch starts rotating in his grave if we touch his baby. I doubt that because Hutch had no problem with input from others, and he was always a fan of elegant code.

What's your opinion?

NoCforMe

Heh; funny that when I used StdOut() in a console app (32-bit), I had no idea that it was a homegrown MASM32 creation, only that it was a hell of a lot easier than using raw WriteFile() or WriteConsole(). (I thought it was a Win32 thing.) So good going there.

Regarding your proposed change, I don't know if I have standing here, since I'm not a 64-bit user, but my vote would be sure, go ahead: just make sure you test it, at least test it more than I usually do. ("Hey, it assembles and links: ship it!")
Assembly language programming should be fun. That's why I do it.

jj2007

Quote from: NoCforMe on September 06, 2023, 04:10:56 AMmy vote would be sure, go ahead: just make sure you test it

For testing, 33 bytes instead of 56:

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
StdOutExtreme proc lpszText:DWORD
    push NULL ; we assume that WriteFile writes to bWritten only when
    push esp ; it's finished, so lpOverlapped can be misused here
    push rv(StrLen, [esp+4+8]) ; lpszText
    push [esp+4+12] ; lpszText
    push rv(GetStdHandle, STD_OUTPUT_HANDLE)
    call WriteFile ; invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL
    retn 4
StdOutExtreme endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
:smiley:

zedd151

I would hold off until we get any information back from stoo23, regarding hutch's Masm64 SDK files. I know that there are numerous fixes scattered here and there in the forum, but possibly hutch had them all in one place for inclusion in the next beta or even release version of the SDK.

Other members also have customized fixes, or additions, that they have added to their own copy of the SDK. Would take some effort getting everything together (assuming the other members would like to contribute to this effort).

Just my two cents worth on the issue.

daydreamer

I would prefer we continue improve masm64 sdk or if it's suppose not be touched, might turn to use and improve alternative 64 bit package?
But that feels like hutch work is invain if we don't use it/ improve it

my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

NoCforMe

Can I make a suggestion here? I think what's needed, unfortunately, is a little bureaucratic process to make sure that any changes like this are tested thoroughly, even if it's something as trivial as this example. That way we'll avoid gnashing of teeth and rending of garments by users who find bugs.

My suggestion is to make sure any changes are tested by someone other than whoever made the change. (Like how one should never try to proofread their own writing.) Then the change can be signed off on and published.

Again, I have little standing on this issue since I don't use any of the 64-bit stuff and am not likely to anytime soon. But I still think this is a good suggestion. (Let's keep it simple, though. No need for excess red tape around here!)
Assembly language programming should be fun. That's why I do it.

Caché GB

A word to the wize.

If you are going to build a MASM 64 bit sdk with the hopes of makeing it
one size fits all you are going to end up playing whack a mole

This is the why Microsoft did not include ml's built in preprocessor
macros like invoke, .if .else, .repeat .until, etc in ml64.

Also to do so you will cripple your code's runtime to a crawl, may as well use 32 bit.

Here is a 64 bit not so extreme version of StdOut.

Remember RAM is cheap, time, not so much.

include \masm64\include64\masm64rt.inc

option prologue:none  ;; <- Undo MASM64 SDK's STACKFRAME macro in masm64rt.inc
option epilogue:none

StdOut proc ;; lpszText:ptr byte  <- no rbp basesd stack so leave off

            add  rsp, -38h

            mov  [rsp+40h], rcx    ; using caller's shadow space

        invoke  GetStdHandle, STD_OUTPUT_HANDLE

            mov  rcx, [rsp+40h]
            sub  rcx, 1
        @SO00A:
            add  rcx, 1
            cmp  byte ptr[rcx], 0
            jnz  @SO00A
            sub  rcx, [rsp+40h]

        invoke  WriteFile, rax, [rsp+40h], rcx, &[rsp+30h] , null  ;; [rsp+30h] = qWritten:qword
            mov  rax, [rsp+30h]

            add  rsp, 38h
            ret

StdOut endp

Test at our own risk.
Caché GB's 1 and 0-nly language:MASM

Caché GB

I made StdOut more extreme

option prologue:none
option epilogue:none

StdOut proc ;; lpszText:ptr byte  <- no rbp basesd stack so leave off
 
            add  rsp, -38h

            mov  [rsp+40h], rcx             ; using caller's shadow space

            mov  ecx, STD_OUTPUT_HANDLE
           call  GetStdHandle

            mov   r8, [rsp+40h]             ; inline StrLen
            sub   r8, 1
        @SO00A:
            add   r8, 1
            cmp   byte ptr[r8], 0
            jnz   @SO00A
            sub   r8, [rsp+40h]

            and  qword ptr[rsp+20h], 0
            lea   r9, [rsp+30h]             ; [rsp+30h] = qWritten:qword
            mov  rdx, [rsp+40h]
            mov  rcx, rax
           call  WriteFile

            mov  rax, [rsp+30h]

            add  rsp, 38h
            ret

StdOut endp

If you wish to bench press this against another version.

        counter  equ  100000000

            mov  r14, counter
         @Loop1:

            lea  rcx, MyString
           call  StdOut_Old

            dec  r14
            jnz  @Loop1


            mov  r14, counter
         @Loop2:

            lea  rcx, MyString
           call  StdOut_New

            dec  r14
            jnz  @Loop2

Replace the API call WriteFile with WriteFileEmpty in the two StdOut functions

WriteFileEmpty proc

            ret

WriteFileEmpty endp

Test at our own risk.
Caché GB's 1 and 0-nly language:MASM

jj2007

#8
Quote from: zedd151 on September 06, 2023, 05:16:55 AMI would hold off until we get any information back from stoo23, regarding hutch's Masm64 SDK files. I know that there are numerous fixes scattered here and there in the forum, but possibly hutch had them all in one place for inclusion in the next beta or even release version of the SDK.

Right, we are not in a hurry. I doubt that new stuff will pop up from Hutch' files, but we can certainly wait.

I am bit worried about too much parallel work. The success of the Masm32 SDK was based on a) quality and b) no competition. I know this sounds odd, as competition is usually good, but here we have a very small niche that survived only because members of this forum, Hutch in the first place, worked together instead of competing. I wish this could happen with the Masm64 SDK, too.

P.S., just for fun (source & exe attached, pure Masm32 SDK code):
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
StdOutExtreme proc lpszText:DWORD
  pop eax ; ret addr
  pop ecx ; string to print
  push eax ; ret addr
  push NULL ; we assume that WriteFile writes to bWritten only when
  push esp ; it's finished, so lpOverlapped can be misused here
  push rv(szLen, ecx) ; lpszText
  push ecx  ; lpszText
  push rv(GetStdHandle, STD_OUTPUT_HANDLE)
  call WriteFile ; invoke WriteFile,hOutPut,lpszText,sl,ADDR bWritten,NULL
  retn
StdOutExtreme endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

Result: 50% less size...
Hello World StdOut
Hello World StdOutExtreme
56 bytes for StdOut
28 bytes for StdOutExtreme

daydreamer

Improve masm64 sdk,need to be done with good example code thats helpful like Iczelion's example code

Masm32 SDK has lots of example code,would port those to 64bit be good idea?
Multithreading examples, would be useful when you can access 64GB in 64bit mode
Or make examples in an area where you only know?
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

jj2007

Quote from: daydreamer on September 07, 2023, 01:39:22 PMImprove masm64 sdk,need to be done with good example code

Check \Masm64\Examples, there are over 100 *.asm files

jj2007

In the Lab you'll find an example how to speed up the frequently used library function szLen by a factor 4 :biggrin:

Caché GB

Quote from: daydreamer on September 07, 2023, 01:39:22 PMImprove masm64 sdk,need to be done with good example code thats helpful like Iczelion's example code

Hi daydreamer

A friend of mine, a c# coder, was curious about MASM. To cut a long story short I
ported Iczelion's tutorial 10.1 to both C++ and MASM 64 bit for him to checkout.

I am dropping them here for your, and any one elses, pleasure. They are Visual Sudio projects. The MASM
version does not require the MASM64 SDK as it was made for a friend of mine and is cut from my homegrown SDK.

Iczelion_x64_10_1 = MASM x64 version
Iczelion_x64_10_2 = C++ version

if you need to ask any questions, go right ahead.

Disclaimer:
1) I am not a technical writer.
2) My PA has not proofread this.
3) There may be errors.

Enjoy.
Caché GB's 1 and 0-nly language:MASM

Vortex

Hi Caché,

QuoteThis is the why Microsoft did not include ml's built in preprocessor
macros like invoke, .if .else, .repeat .until, etc in ml64.

The reason of removing those high level language elements was to discourage people from using their own assembler. M$ is rather promoting the C\C++\C# compiler set. The decision is based on commercial reasons.

Caché GB

Hi Vortex

Thanks for the correction. Can we at least agree to disagree that if Microsoft did include ml's
built in preprocessor macros, ml64 would be more like a mini compiler than an assembler. Yes, no?

Should we improve the Masm64 SDK? No. We should rebuild it. Refactor it. Make it second to none.
Caché GB's 1 and 0-nly language:MASM