The MASM Forum

64 bit assembler => 64 bit assembler. Conceptual Issues => Topic started by: jj2007 on July 16, 2016, 11:48:29 AM

Title: 64-bit assembly starter kit
Post by: jj2007 on July 16, 2016, 11:48:29 AM
See Dual 64/32-bit assembly (http://masm32.com/board/index.php?topic=94.msg58968#msg58968) in the MasmBasic thread. On my machine, both the console and the GUI example assemble fine with ML64, AsmC, HJWasm and JWasm. Work in progress, though - it's more a proof of concept than anything else.

Note that the new jinvoke macro does indeed check the number and type of parameters, even with Microsoft's poor crippled 64-bit version of the once powerful MASM assembler. This is my version of progress 8)
Title: 64-bit vs 32-bit code sizes
Post by: jj2007 on July 16, 2016, 06:46:51 PM
I had to update the library (http://masm32.com/board/index.php?topic=94.0) once more, sorry :(

Based on the sources that appear when clicking File/New Masm source in RichMasm as "Dual 32/64 bit console/GUI", I get (see attachment) the following code sizes:
2048 console 32-bit
2560 console 64-bit
6144 windows 32-bit
8192 windows 64-bit


So 64-bit code is definitely longer, although the effect is not dramatic 8)
(Windows6 by Hutch (http://masm32.com/board/index.php?topic=5482.msg58709#msg58709) is a bit longer, but that is because of the bigger icon)

P.S.: The GUI versions feature a simple window with an edit control and a menu, with WM_ messages shown in the console. The more boring ones like WM_MOUSEMOVE are filtered out. So far I haven't seen message differences between 64- and 32-bit code.
Title: Re: 64-bit assembly starter kit
Post by: sinsi on July 16, 2016, 07:18:38 PM
Without source code it's hard to tell, but if you are using "mov ebx,OFFSET var" that is longer than "lea ebx,[var]" (4 bytes extra?).
With ML64, using lea will use rip-relative addressing, the only catch is that var needs to be within +-2GB.
This allows for proper position independent code too.

Another cause of bloat is adjusting the stack for each API call, can end up as code like

sub rsp,20h
call API_1
add rsp,20h
sub rsp,20h
call API_2
add rsp,20h
sub rsp,20h
call API_3
add rsp,20h
...

If you write your own prologue you can pass "maximum param bytes" in the PROC declaration and adjust the stack once.

One big gotcha is what happens to the upper 32 bits of a register when you manipulate the lower 32 bits.
"sub eax,eax" will zero the top 32 bits of rax. So "sub eax,eax" is the same as "sub rax,rax" except one byte smaller (no rex prefix).
A common way to get two 16-bit numbers into a 32-bit register, extended to 32 and 64

mov ax,high16
shl eax,16
mov ax,dx
;
mov eax,high32
shl rax,32
mov eax,edx ;oops, high32 of rax now 0

Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 16, 2016, 08:04:26 PM
Quote from: sinsi on July 16, 2016, 07:18:38 PMif you are using "mov ebx,OFFSET var" that is longer than "lea ebx,[var]" (4 bytes extra?).

Good point, already corrected and uploaded (there were only a few instances where it mattered, though) :t

QuoteAnother cause of bloat is adjusting the stack for each API call, can end up as code like
Hmmmmmmm...

sub rsp,20h  ; once on top
push rcx   ; save a reg
call API_1
pop rcx   ; pop saved reg????

push rcx   ; save a reg
call API_2
pop rcx   ; pop saved reg????

add rsp,20h  ; once at endp


QuoteA common way to get two 16-bit numbers into a 32-bit register, extended to 32 and 64
Valid point, thanks. Keep in mind that movzx works with 16-bit operands:
48 0F B7 55 2A    movzx rdx, word ptr ss:[rbp+2A]
Title: Re: 64-bit assembly starter kit
Post by: sinsi on July 16, 2016, 08:29:00 PM
Why?

push rcx   ; save a reg


Same thing, 48=REX prefix (register extension?)

seg000:0000000000000000 48 0F B7 55 2A                          movzx   rdx, word ptr [rbp+2Ah]
seg000:0000000000000005 0F B7 55 2A                             movzx   edx, word ptr [rbp+2Ah]
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 16, 2016, 08:33:27 PM
Quote from: sinsi on July 16, 2016, 08:29:00 PM
Why?

push rcx   ; save a reg

Why not? I always save values with a push/pop pair 8)

QuoteSame thing, 48=REX prefix (register extension?)

seg000:0000000000000000 48 0F B7 55 2A                          movzx   rdx, word ptr [rbp+2Ah]
seg000:0000000000000005 0F B7 55 2A                             movzx   edx, word ptr [rbp+2Ah]
Good catch indeed, thanks.
Title: Re: 64-bit assembly starter kit
Post by: sinsi on July 16, 2016, 09:16:28 PM
Save a reg, unalign the stack...
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 18, 2016, 07:27:08 AM
MSDN: (https://msdn.microsoft.com/en-us/library/9kkd4k7y.aspx)
QuoteINVOKE
Visual Studio 2015
Other Versions

Calls the procedure at the address given by expression, passing the arguments on the stack or in registers

Did I miss something? My ML claims to be Microsoft (R) Macro Assembler (x64) Version 10.00.30319.01, and it considers invoke a syntax error...
Title: Re: 64-bit assembly starter kit
Post by: habran on July 18, 2016, 08:57:37 AM
ML64 is dumb, it doesn't understand any HLL :icon13:
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 18, 2016, 11:33:01 AM
Quote from: habran on July 18, 2016, 08:57:37 AM
ML64 is dumb, it doesn't understand any HLL :icon13:

So why do they mention INVOKE in the VS 2015 docs??
Title: Re: 64-bit assembly starter kit
Post by: rrr314159 on July 18, 2016, 11:55:08 AM
VS 2015 is actually 32-bit application. It can make 64-bit code but (I suppose) you can still use it with ML 32-bit
Title: Re: 64-bit assembly starter kit
Post by: hutch-- on July 18, 2016, 12:44:48 PM
 :biggrin:

Some of the things you guys say makes me laugh. When Iczelion and I started on ML.EXE in 1997 it had almost no documentation except a 16 bit help file called "alang.hlp", it was sh*t canned by everyone as useless, out of date and not as good as TASM and it could not be written by programmers. Some months later the idiots shoved their foot back in their mouth when we got it up and going. ML.EXE was a bad mannered old pig even back then but it kicked arse big time when it came to results. I confess I had a lot of fun with a toy I wrote years ago called "thegun.exe" at a disgusting 6k up and running.

Neither ML.EXE or ML64.EXE are consumer software, they don't hold your hot little hand and if you make a PHUKUP it will bite you, they are industrial tools for creating object modules for executable and DLL files. Now as everyone is playing catchup by emulating MASM macros, ML64 has no problems emulating "invoke", ".if" and the rest of the control flow options. ".switch" came easily, multiple "invoke" variations were trivial and library modules are routine. I am not a fan of the assembler wars having spent some years brawling there but when push comes to shove, MASM has been in development since 1982 and is still going with a 64 bit version that is at least as bad mannered as any of the earlier versions.  :P

Now think of the days in 1990 when you could write 16 bit assembler that looked like a CodeView debug session, you could tell the men from the boys by the paper they used. (large sheet of 0000 sandpaper).  :biggrin:
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 18, 2016, 06:56:11 PM
Quote from: hutch-- on July 18, 2016, 12:44:48 PMwith a 64 bit version that is at least as bad mannered as any of the earlier versions

Apart from being CrippleWare, ML64 complains randomly about "invalid character in file". On second attempt with identical files, it usually works. Probably they haven't understood the X64 ABI in Redmond 8)

Stupid noob question: Do all local variables need to be individually aligned 16? I ran into trouble with a "misaligned" PAINTSTRUCT 8)

If that is the case, it would imply that all QWORD locals need to waste an extra 8 bytes ::)
And when reading what Hutch coded as Local64 (http://masm32.com/board/index.php?topic=5462.0), this really seems to be the requirement... what a mess!
Title: Re: 64-bit assembly starter kit
Post by: qWord on July 18, 2016, 11:15:40 PM
Quote from: jj2007 on July 18, 2016, 06:56:11 PM
Quote from: hutch-- on July 18, 2016, 12:44:48 PMwith a 64 bit version that is at least as bad mannered as any of the earlier versions
Stupid noob question: Do all local variables need to be individually aligned 16?
The actual needed alignment depends on the concrete structure and is determined by the structure member (resp. member in sub-structure) with the largest alignment constraint. For the WinAPI the default structure member alignment (https://msdn.microsoft.com/en-us/library/xh3e3fd0.aspx) is set to 8, means that alignment never gets larger than 8, but might be smaller.

Quote from: Aggregates and Unions (https://msdn.microsoft.com/en-us/library/9dbwhz68.aspx)The alignment of the beginning of a structure or a union is the maximum alignment of any individual member. Each member within the structure or union must be placed at its proper alignment as defined in the previous table, which may require implicit internal padding, depending on the previous member.

For PAINTSTRUCT 8 is required (because of HDC) and, e.g., for RECT 4 is sufficient.

EDIT: forgot to mention the default structure alignment
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 19, 2016, 02:47:52 AM
Thanks, qWord. I guess even ML64 can align structures, but what about the local variables? Hutch has chosen this approach (http://masm32.com/board/index.php?topic=5462.0):  ; LOCAL64 macro is to maintain stack alignment of locals.
  ; each macro adds a dummy local after the named LOCAL to add
  ; an extra 8 bytes to the stack.


Which I interpret that the start address (rbp+x) of every ps and rc must be aligned to 16-bit, for use with movaps and friends. Or am I wrong?
Title: Re: 64-bit assembly starter kit
Post by: hutch-- on July 19, 2016, 04:53:33 AM
Any struct that I have written in win64 is done like so.


strname STRUCT QWORD
  ; members dtype ? etc ....
strname ENDS


With the macros "LOCAL64 and STRUCT64" they are written in the uninitialised data section so the data is independent from the stack so I can use them anywhere in the code section without having to put them at the top like normal LOCAL variables but you can also use them in procedures with no stack frame.
Title: Re: 64-bit assembly starter kit
Post by: qWord on July 19, 2016, 04:59:16 AM
The problem is the default prolog/epilogue, which does not respect the alignment constraints for fastcall nor the structure member alignment of 8 (Zp8 or direct). Conclusion => setup your own prologue/epilogue macro (straight forward). The second step is to write  LOCAL-replacement that does add padding to 8 bytes for structure member alignment (or, as Hutch, 16 if wished)..


BTW: I'm curious what all these 64-suffixes are good for:-D
Title: Re: 64-bit assembly starter kit
Post by: hutch-- on July 19, 2016, 05:15:17 AM
 :biggrin:

> BTW: I'm curious what all these 64-postfixes are good for:-D

It was just a naming convenience so I knew what they were for. Now interestingly enough, if you write the "proc" line in the same way as 32 bit ML with specified data types "item:QWORD" you get the first 4 arguments that correspond to the 64 bit calling convention blank and from argument 5 onwards the arguments contain the right data so I have used the following,


    mov QWORD PTR [rbp+10h], rcx
    mov QWORD PTR [rbp+18h], rdx
    mov QWORD PTR [rbp+20h], r8
    mov QWORD PTR [rbp+28h], r9


This preserves the registers so they are not overwritten by any other procedure call and you can use the names from the "proc" line once the data is copied to the stack. it also means that you have rax rcx rdx r8 r9 r10 and r11 as volatile registers to use in the algo if needed and that is before preserving any of the non-volatile registers so if you need it you can have genuine PHUN in algo design.
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 19, 2016, 06:02:48 AM
Quote from: qWord on July 19, 2016, 04:59:16 AMThe second step is to write  LOCAL-replacement that does add padding to 8 bytes

This is the part where I fail to see the logic. The X64 ABI makes a big fuzz about the stack being align 16, and I always thought it's because of SIMD instructions being faster or requiring such alignment. But why then align 8 for local variables? It doesn't make sense 8)
Title: Re: 64-bit assembly starter kit
Post by: qWord on July 19, 2016, 06:30:20 AM
Quote from: jj2007 on July 19, 2016, 06:02:48 AMBut why then align 8 for local variables? It doesn't make sense 8)
To save memory of course. Even for compilers it is no problem to keep track of the alignment and reorder locals to get best results. Actual this problem is specific to ml64 and its broken HLL capacities**.
Remarks that the structure alignment applies to all segments and not just the stack!

**when doing low-level assembler programming it no problem of course
Title: Re: 64-bit assembly starter kit
Post by: mineiro on July 19, 2016, 06:52:27 AM
You can see this problem better if you think with odd, even, odd, even, ... . Or at some point with even, odd, even, odd, ... .
On entry point of our windows program, rsp=???8.

Before we do a 'call' stack should be 16 bytes aligned, so we should subtract from rsp 8 bytes to get rsp=???0 and after do a call, and on procedure entry rsp is back again to rsp=???8.

Suppose we call a function that have 4 parameters only and configuration below:

4*8 because rcx,rdx,r8,r9 will be saved on stack, like function parameters.
7*8 because locals
3*8 because I'm supposing that a function that have maximum parameters inside this procedure have 7 parameters, the first 4 goes into registers, so we need 3 on stack, and this space will be reusable by all others functions with minimum parameters. We setup to biggest parameter functions.

So our prologue can be
sub rsp, (4*8+7*8+3*8 ) == 4+7+3==14, the result is even, this is not ok because rsp=???8(odd). We need insert a foo (1*8 ) to stack get aligned into this prologue.
This way you can free rbp.

Other way is:
on entry point of our program, rsp=???8, but if we just do a call to a procedure without parameters, like 'call main', so this will align stack to 16 bytes multiple.
This is why I said about odds and evens, and my opinions this is the real challenge on coding to x86-64 O.S. (the same problem on linux side, just entry point is aligned to 16 bytes instead of 8 bytes, and instead of 4 shadows you have 6 shadows (both are even)). But I'm not talking about non volatile registers into this context, so, odds and evens again.

Dword locals are pseudo promoted to qwords, this is why it is a qword as have been said.

A simple test is, call at entry point printf function with 7 parameters, after with 8. One of these will be invalid.
So, now do the same as before but now with stack aligned, one of that will be invalid again.
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 19, 2016, 10:19:21 AM
Quote from: qWord on July 19, 2016, 06:30:20 AM
Quote from: jj2007 on July 19, 2016, 06:02:48 AMBut why then align 8 for local variables? It doesn't make sense 8)
To save memory of course.

I meant the opposite: If they want the stack align 16, why only align for a RECT? For a movaps xmm0, rc, you really need align 16 8)

QuoteAlignment (https://msdn.microsoft.com/en-us/library/ms235286.aspx)
Most structures are aligned to their natural alignment. The primary exceptions are the stack pointer and malloc or alloca memory, which are aligned to 16 byte

"Most" is nice :eusa_boohoo:

Besides, that stack alignment story should be investigated. Insert the equivalent of PrintLine Hex$(rsp) in your WndProc and see something amazing...
Title: Re: 64-bit assembly starter kit
Post by: qWord on July 19, 2016, 12:38:06 PM
Quote from: jj2007 on July 19, 2016, 10:19:21 AM
I meant the opposite: If they want the stack align 16, why only align for a RECT? For a movaps xmm0, rc, you really need align 16 8)
there is no conflict: you have a defined alignment on entry thus you can align the locals as you like.
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 19, 2016, 11:06:29 PM
Quote from: qWord on July 19, 2016, 12:38:06 PMthere is no conflict: you have a defined alignment on entry thus you can align the locals as you like.

It doesn't seem so straightforward. In my tests, the WM_PAINT handler crashes if the PAINTSTRUCT is local, it works with a global ps. Padding with an extra qword left or right won't help. Apparently I've got the spill space wrong, BeginPaint writes into my locals :(

Besides, on entry into the WndProc, the stack is aligned to 8 bytes, not to 16. Windows doesn't follow the 16-bit alignment rule 8)
Title: Dual 64/32-bit assembly
Post by: jj2007 on July 22, 2016, 10:16:38 AM
include \Masm32\MasmBasic\Res\JBasic.inc      ; click to download version 22 July 2016 (http://masm32.com/board/index.php?topic=94.0)
; ### simple console demo, assembles in 32- or 64-bit mode with ML, AsmC, JWasm, HJWasm ###
j@start            ; OPT_64 1      ; put 0 for 32 bit, 1 for 64 bit assembly
  PrintLine Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format")      ; OPT_Assembler ML      ; make sure you got the right versions
  Print Str$(" \ntest with multiple tabbed args:\n\t%i\t%i\t%i\n\n", 12, 13, 14)
  Print "Type a number: "
  Print Str$("The value of your number is %i\n", Val(Input$()))
  Print Chr$(jbit$, "-bit assembly is easy, it seems...")
j@end


Output:
This code was assembled with ml64 in 64-bit format

test with multiple tabbed args:
        12      13      14

Type a number: 123.456
The value of your number is 123
64-bit assembly is easy, it seems...


No 64-bit libraries required, a standard Masm32 installation plus MasmBasic are sufficient. Code sizes are slightly higher for 64-bit code, although the snippet above builds at 2048 bytes for both the 64- and 32-bit versions.

Attached a simple window with a RichEdit control. Open in RichMasm and hit F6.
EDIT: Removed. Use the new one further down, or go to menu File/New Masm source in RichMasm.
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 28, 2016, 06:23:58 PM
Quote from: sinsi on July 16, 2016, 07:18:38 PMIf you write your own prologue you can pass "maximum param bytes" in the PROC declaration and adjust the stack once.

Implemented in the latest MasmBasic release.

QuoteOne big gotcha is what happens to the upper 32 bits of a register when you manipulate the lower 32 bits.
"sub eax,eax" will zero the top 32 bits of rax. So "sub eax,eax" is the same as "sub rax,rax" except one byte smaller (no rex prefix).

Just stumbled over this one:
| 48 31 C0                  | xor rax, rax                      |
| 83 C8 FF                  | or eax, FFFFFFFF                  |
| 48 0D FF FF FF FF         | or rax, FFFFFFFFFFFFFFFF          |
| 31 C0                     | xor eax, eax                      |
| 48 31 C0                  | xor rax, rax                      |


Looks harmless but attention, one of the instructions does not behave as you expect it ::)
Title: Re: 64-bit assembly starter kit
Post by: Mikl__ on July 28, 2016, 10:51:27 PM
Ciao, jj2007!
xor eax, eax => movsx rax,eax => mov rax,0000000000000000h
or eax, 0FFFFFFFFh => movsx rax,eax => mov rax,0FFFFFFFFFFFFFFFFh
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on July 28, 2016, 11:17:45 PM
Yes, exactly, that's the one:
   int 3
   xor rax, rax                     
   or eax, -1   ; no movsx rax,eax!!!
   or rax, -1
   xor eax, eax
   xor rax, rax


But sinsi wrote indeed "zero the top 32 bits of rax". Would movzx rax, eax be the correct rule in all cases?
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on August 06, 2016, 10:37:03 PM
For the fans of qEditor:
- install the latest MasmBasic package
- run the 64-bit example once, i.e. click on (similar as 64-bit code) in line 12 of MbGuide.rtf and hit F6
- add a line in \Masm32\menus.ini e.g. under "console build all":
Build+Run &64,\MASM32\MasmBasic\Res\Bldallc64.bat "{b}"
- move the attached batch file to its location
- open one of the attached examples in qEditor and go to the Project menu
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on August 30, 2016, 11:47:13 AM
Update 30 August 2016 (download (http://masm32.com/board/index.php?topic=94.0)):

During installation, you will see the MbGuide file (greenish background). Select Init in the (lower) 64-bit example on the first page, then hit F6.

Or, better, click on menu File/New Masm source, then on Dual 32/64 bit console/GUI templates that compile both as 64 and 32-bit applications

Feedback needed, this is not yet a stable release but for me it works fine. However, I wasted several hours chasing mysterious ML64 bugs, including "internal error" with hex dumps staring at me, for a source that had absolutely no problem with JWasm, HJWasm and AsmC. Besides, ML complains every now and then about "invalid characters" in the source; when retrying with the same identical file, it doesn't find the problem any more. Time to ditch this beast in favour of better and faster assemblers (where are you, Habran, Johnsa and Nidud??).

The current versions of the console and GUI templates (attached), though, still compile with all assemblers tested, in 64- and 32-bit mode. All you need is the current Masm32 installation plus MasmBasic - no other libs required. Btw, even with ML64, the jinvoke macro counts the CreateWindowEx parameters and barks at you if there aren't exactly 12 of them 8)

P.S. for the developers: have a look at \Masm32\MasmBasic\Res\DualWin.inc (search for SIZE_P)
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on September 03, 2016, 10:00:37 AM
Seven downloads, no feedback? Does that mean it works fine for everybody???
Title: Subclassing a RichEdit control, 64- and 32-bit code
Post by: jj2007 on October 02, 2016, 12:02:51 PM
Here is a dual 64/32-bit assembly example that does indeed require one line of conditional assembly:

if @64
mov opEdit, rv(SetWindowLongPtrW, rbx, GWL_WNDPROC, SubEdit)
else
mov opEdit, rv(SetWindowLongW, rbx, GWL_WNDPROC, SubEdit)
endif


Source attached, builds as 64- or 32-bit code with ML64/ML, HJWasm and AsmC. Requires the standard Masm32 package and current MasmBasic (http://masm32.com/board/index.php?topic=94.0), no further libraries needed.

P.S.: Here is the subclass proc - it looks a bit messy because ML64 has no native switch command:
SubEdit proc <cb> hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
  cmp uMsg, WM_KEYDOWN
  jne @F
  cmp wParam, VK_ESCAPE ; close the app if user hits Escape
  jne @Endswitch
  jinvoke SendMessage, rv(GetParent, hwnd), WM_CLOSE, 0, 0
  jmp @Endswitch
@@:
  cmp uMsg, WM_CHAR
  jne @Endswitch
  cmp wParam, "e"
  jne @Endswitch
  mov wParam, "E"
@Endswitch:
  jinvoke CallWindowProcW, opEdit, hwnd, uMsg, wParam, lParam
  ret
SubEdit endp
Title: Re: 64-bit assembly starter kit
Post by: hutch-- on October 02, 2016, 12:43:41 PM
This is the advantage of a non configured assembler like ML64, as its a MACRO assembler, use a "switch" macro.  :biggrin:

    .switch uMsg
      .case WM_INITDIALOG
      ; ------------------------------------------------------
      ; lParam is the icon handle passed from DialogBoxParam()
      ; ------------------------------------------------------
        invoke SendMessage,hWin,WM_SETICON,1,lParam     ; set the icon for the dialog
        invoke SendMessage,rv(GetDlgItem,hWin,102), \   ; set the icon in the client area
               STM_SETIMAGE,IMAGE_ICON,lParam
        invoke SetWindowText,hWin,"Create Base Dialog Template"
        .return TRUE

      .case WM_COMMAND
        .switch wParam
          .case 101
            jmp exit_dialog             ; The OK button

          .case 102
            invoke MessageBox,hWin,"Create Project","dlgmake",MB_OK

          .case 103
            invoke MessageBox,hWin,"Build Project","dlgmake",MB_OK

          .case 104
            invoke MessageBox,hWin,"Test Project","dlgmake",MB_OK

          .case 105
            invoke MessageBox,hWin,"Get target","dlgmake",MB_OK

        .endsw

      .case WM_CLOSE
        exit_dialog:
        invoke EndDialog,hWin,0         ; exit from system menu
    .endsw

Pure, clean simple MASM code.  :P
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on October 02, 2016, 06:32:58 PM
Quote from: hutch-- on October 02, 2016, 12:43:41 PM
This is the advantage of a non configured assembler like ML64, as its a MACRO assembler, use a "switch" macro.  :biggrin:

We've discussed that already in the CrippleWare thread (http://masm32.com/board/index.php?topic=5662.0). You won't convince me to write .if eax {= ecx :(
Title: Re: 64-bit assembly starter kit
Post by: hutch-- on October 02, 2016, 07:09:58 PM
 :biggrin:

The problem is that your view on ML64 is crippled, however you may wish to misrepresent it, its up and going, has full libraries and includes, is backed by Microsoft who need it themselves and its not trying to be a backdoor C compiler. No weird syntax, no C typedefed data types, hex in MASM notation and just clean fast 64 bit assembler. All of the joys of a true MACRO assembler without the C yukkies.  :P
Title: Re: 64-bit assembly starter kit
Post by: rrr314159 on October 03, 2016, 02:16:38 AM
Plus it's got no bugs, but plenty of cool features I don't understand! Doesn't get any better than that.

You're right about one thing: it's not trying to be C or C++. Assemblers should be proud to be assemblers.

Bumper Sticker ideas: "ML64 coders push and pop all night long" "Invoke this, HJWasm coders!"
Title: Re: 64-bit assembly starter kit
Post by: nidud on October 03, 2016, 02:36:57 AM
deleted
Title: Re: 64-bit assembly starter kit
Post by: hutch-- on October 03, 2016, 08:13:56 AM
 :biggrin:

> Plus it's got no bugs, but plenty of cool features I don't understand! Doesn't get any better than that.

Of course it has no bugs and very advanced error reporting, the only weakness is the (ab)user so it has highly advanced error reporting (multiple screens of chyte) to ensure that the (ab)user fully understands that there is an error in the code. They then have to master decrypting the multiple screens of chyte without anyone holding their hot little hand.

Now translate this into what its purpose is, a boiler room industrial tool for crunching mnemonics that the (ab)user is supposed to know how to use that will bite them on the hand if they get it wrong. Now the macro engine is something else, a dinosaur from the 1990 version of ML.EXE that has survived from 16 to 32 and now 64 bit, bugz 'n all (whoops I mean features) so if you could write macros in 1990, you still know how to use the ML64 macro engine.

I am personally a fan of "suicide" coding in that it very quickly teaches you to get it right the first time or it will explode in your face. SEH and the like are for the limp of wrist, the idea is write error free code in the first place and with practice, become efficient at it.
Title: Re: 64-bit assembly starter kit
Post by: rrr314159 on October 03, 2016, 02:51:28 PM
Quote from: hutch-- on October 03, 2016, 08:13:56 AMSEH and the like are for the limp of wrist, the idea is write error free code in the first place ...

Sure.
Title: Re: 64-bit assembly starter kit
Post by: hutch-- on October 03, 2016, 03:47:49 PM
rrr,

You don't sound altogether convinced.  ::)
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on October 03, 2016, 05:06:08 PM
Quote from: hutch-- on October 03, 2016, 08:13:56 AMSEH and the like are for the limp of wrist, the idea is write error free code in the first place

I've implemented SEH in my package (as Try/Catch/Finally), but I rarely use it. When official Microsoft software confronts the end user with "error 0x8000c0005", it's usually a clear indication that the only thing that they still control and understand in their pile of shyte is the exception handler :P
Title: Re: 64-bit assembly starter kit
Post by: hutch-- on October 03, 2016, 05:21:15 PM
> I've implemented SEH in my package (as Try/Catch/Finally)

My condolences.  :P
Title: Re: 64-bit assembly starter kit
Post by: rrr314159 on October 03, 2016, 09:13:24 PM
Quote from: rrr314159 on October 03, 2016, 02:51:28 PM
Quote from: hutch-- on October 03, 2016, 08:13:56 AMSEH and the like are for the limp of wrist, the idea is write error free code in the first place ...

Sure.

Quote from: hutch-- on October 03, 2016, 03:47:49 PM
rrr, You don't sound altogether convinced.  ::)
If my response was lukewarm, it was only because the statement's so obviously true. "Suicide code" is the right idea. If it's going to blow up I want it to do it now, so I can fix it. Not hide the error during development so later on it can explode in the user's face with some completely useless error code. What good is that?
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on October 03, 2016, 10:33:08 PM
I am a great fan of "suicide code". Problem is that with growing complexity of a project (teams of ten developers, millions of lines, ...), and exposure to the Dumbest Imaginable User, the likeliness of totally exceptional exceptions is growing exponentially. It is thus understandable that the C/C++ fraction likes installing SEH by default. Still, I don't think it's a good strategy, since the root cause is that they lost control over a complex project, and therefore the handler may not really "handle" correctly the situation.

In my own tiny projects (RichMasm: 18k lines) I don't use SEH. But I do take care that no files are ever open for more than a second, and that backup text is being saved to disk if a) doc is dirty and b) the editor is idle for more than x seconds. With these precautions, suicide code is fine. No damage possible.
Title: Re: 64-bit assembly starter kit
Post by: hutch-- on October 03, 2016, 10:57:58 PM
There are approaches that beat the sloppy code of late, true tested modular coding where each component is bashed to death until there is nothing wrong with it and it performs correctly to its specification. This of course must be backed up by documentation so its specification is known. Objects are made of components and if the components are proven and reliable, then the object is reliable if its constructed properly.

Abstraction as a matter of style is the enemy here, objects that are poorly understood and often poorly written fail without a direct solution to fix them. The real problem is the quality of idiot is so high that nothing can be made idiot proof and thus, the approach of suicide code, if it fails at the modular level, it never reaches the object level and cannot be messed up by a hick. At the module level it can be fixed and here I am a fan of post mortem debugging where you know exactly where something crashed and why.

My main use of a source code debugger is the disassembly, ArkDasm was indispensable while researching Win64 and what capacity ML64 had.
Title: Re: 64-bit assembly starter kit
Post by: jj2007 on October 04, 2016, 11:58:05 AM
Found this by accident in C:\Program Files (x86)\Windows Kits\8.1\Include\um\DbgHelp.h :(

QuoteImageRvaToVa(
    _In_ PIMAGE_NT_HEADERS NtHeaders,
    _In_ PVOID Base,
    _In_ ULONG Rva,
    _In_opt_ OUT PIMAGE_SECTION_HEADER *LastRvaSection
    );

#ifndef _WIN64
// This api won't be ported to Win64 - Fix your code.

typedef struct _IMAGE_DEBUG_INFORMATION {
    LIST_ENTRY List;

No IMAGE_DEBUG_INFORMATION structure in 64-bit code...
Title: Re: 64-bit assembly starter kit
Post by: TWell on October 04, 2016, 06:16:23 PM
Nor functions that use it ?
Title: Re: 64-bit assembly starter kit
Post by: LiaoMi on October 04, 2016, 09:22:34 PM
Quote from: jj2007 on October 04, 2016, 11:58:05 AM
Found this by accident in C:\Program Files (x86)\Windows Kits\8.1\Include\um\DbgHelp.h :(

QuoteImageRvaToVa(
    _In_ PIMAGE_NT_HEADERS NtHeaders,
    _In_ PVOID Base,
    _In_ ULONG Rva,
    _In_opt_ OUT PIMAGE_SECTION_HEADER *LastRvaSection
    );

#ifndef _WIN64
// This api won't be ported to Win64 - Fix your code.

typedef struct _IMAGE_DEBUG_INFORMATION {
    LIST_ENTRY List;

No IMAGE_DEBUG_INFORMATION structure in 64-bit code...

C:\Program Files (x86)\Windows Kits\8.1\Include\um\ImageHlp.h

Quote#ifndef _WIN64
// This api won't be ported to Win64 - Fix your code.

typedef struct _IMAGE_DEBUG_INFORMATION {
    LIST_ENTRY List;
    DWORD ReservedSize;
    PVOID ReservedMappedBase;
    USHORT ReservedMachine;
    USHORT ReservedCharacteristics;
    DWORD ReservedCheckSum;
    DWORD ImageBase;
    DWORD SizeOfImage;

    DWORD ReservedNumberOfSections;
    PIMAGE_SECTION_HEADER ReservedSections;

    DWORD ReservedExportedNamesSize;
    PSTR ReservedExportedNames;

    DWORD ReservedNumberOfFunctionTableEntries;
    PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries;
    DWORD ReservedLowestFunctionStartingAddress;
    DWORD ReservedHighestFunctionEndingAddress;

    DWORD ReservedNumberOfFpoTableEntries;
    PFPO_DATA ReservedFpoTableEntries;

    DWORD SizeOfCoffSymbols;
    PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols;

    DWORD ReservedSizeOfCodeViewSymbols;
    PVOID ReservedCodeViewSymbols;

    PSTR ImageFilePath;
    PSTR ImageFileName;
    PSTR ReservedDebugFilePath;

    DWORD ReservedTimeDateStamp;

    BOOL  ReservedRomImage;
    PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory;
    DWORD ReservedNumberOfDebugDirectories;

    DWORD ReservedOriginalFunctionTableBaseAddress;

    DWORD Reserved[ 2 ];

} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION;


PIMAGE_DEBUG_INFORMATION
IMAGEAPI
MapDebugInformation(
    _In_opt_ HANDLE FileHandle,
    _In_ PCSTR FileName,
    _In_opt_ PCSTR SymbolPath,
    _In_ ULONG ImageBase
    );

Title: Re: 64-bit assembly starter kit
Post by: jj2007 on October 04, 2016, 10:05:19 PM
Quote from: TWell on October 04, 2016, 06:16:23 PM
Nor functions that use it ?

Quote from: LiaoMi on October 04, 2016, 09:22:34 PM
C:\Program Files (x86)\Windows Kits\8.1\Include\um\ImageHlp.h

Point is that there are a number of functions and structures that are not "portable" between 32- and 64-bit code. I am working on a set of includes that works for both, so that struck my eye.