Author Topic: First time UASM 2.49 user noob question about 32-bit vs 64-bit  (Read 1015 times)

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 6768
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: First time UASM 2.49 user noob question about 32-bit vs 64-bit
« Reply #15 on: September 22, 2019, 01:51:11 PM »
Hi Jose,

> People that like to work on auto-pilot or have his little nice hand guided all the time ((C) Hutch) should consider use only HLL.

I have missed something here, with 64 bit MASM I have the options of no stack frame, an RBP stack frame using either ENTER/LEAVE or combinations of RSP/RBP, yet another option of just aligning the stack via RSP so HLL API functions can be called. Then there is any valid procedure alignment for any data size including ones that have not been created yet.

Have I missed something here ?
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 6768
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: First time UASM 2.49 user noob question about 32-bit vs 64-bit
« Reply #16 on: September 22, 2019, 02:35:32 PM »
Here is a short example of the flexibility of MASM with code generation. ZIP file attached. MASM is a MACRO assembler and it is not trying to be a C compiler, CL does that just fine.

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

    include \masm32\include64\masm64rt.inc

    .data
      MyString db "Once upon a time, the birds chewed lime and monkeys chewed tobacco",0
      pStr dq MyString

    .code

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

 entry_point proc

    USING r12,r13
    LOCAL lstr  :QWORD

    SaveRegs

    rcall getlen,pStr
    mov lstr, rax
    mov rcx, rax

    rcall show1,rcx

    rcall show2,lstr

    rcall show3,lstr

    RestoreRegs
    .exit

 entry_point endp

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

 PROCALIGN

 show1 proc

    rcall MessageBox,0,str$(rcx),"PROCALIGN",MB_OK

    ret

 show1 endp

 STACKFRAME

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

 show2 proc

    rcall MessageBox,0,str$(rcx),"STACKFRAME",MB_OK

    ret

 show2 endp

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

 ALTSTACKFRAME 128, 64

 show3 proc

    rcall MessageBox,0,str$(rcx),"ALTSTACKFRAME",MB_OK

    ret

 show3 endp

  STACKFRAME

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

 NOSTACKFRAME

 getlen proc

    mov rax, rcx
    sub rax, 1
  lbl:
  REPEAT 3
    add rax, 1
    movzx r10, BYTE PTR [rax]
    test r10, r10
    jz lbl1
  ENDM

    add rax, 1
    movzx r10, BYTE PTR [rax]
    test r10, r10
    jnz lbl

  lbl1:
    sub rax, rcx

    ret

 getlen endp

 STACKFRAME

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

    end

 ; .text:0000000140001000 C8800000                   enter 0x80, 0x0
 ; .text:0000000140001004 4881EC80000000             sub rsp, 0x80
 ; .text:000000014000100b 4C896588                   mov qword ptr [rbp-0x78], r12
 ; .text:000000014000100f 4C896D90                   mov qword ptr [rbp-0x70], r13
 ; .text:0000000140001013 488B0D85100000             mov rcx, qword ptr [0x14000209f]
 ; .text:000000014000101a E8F5000000                 call sub_140001114
 ; .text:000000014000101a
 ; .text:000000014000101f 48894580                   mov qword ptr [rbp-0x80], rax
 ; .text:0000000140001023 488BC8                     mov rcx, rax
 ; .text:0000000140001026 488BC9                     mov rcx, rcx
 ; .text:0000000140001029 E827000000                 call sub_140001055
 ; .text:0000000140001029
 ; .text:000000014000102e 488B4D80                   mov rcx, qword ptr [rbp-0x80]
 ; .text:0000000140001032 E85C000000                 call sub_140001093
 ; .text:0000000140001032
 ; .text:0000000140001037 488B4D80                   mov rcx, qword ptr [rbp-0x80]
 ; .text:000000014000103b E892000000                 call sub_1400010d2
 ; .text:000000014000103b
 ; .text:0000000140001040 4C8B6588                   mov r12, qword ptr [rbp-0x78]
 ; .text:0000000140001044 4C8B6D90                   mov r13, qword ptr [rbp-0x70]
 ; .text:0000000140001048 48C7C100000000             mov rcx, 0x0
 ; .text:000000014000104f FF1533110000               call qword ptr [ExitProcess]
 ; .text:000000014000104f
 ; ; --------------------------------------------------------------------------
 ; ; sub_140001055
 ; ; --------------------------------------------------------------------------
 ; sub_140001055   proc
 ; .text:0000000140001055 4883EC08                   sub rsp, 8
 ; .text:0000000140001059 488BC9                     mov rcx, rcx
 ; .text:000000014000105c 488B1544100000             mov rdx, qword ptr [0x1400020a7]
 ; .text:0000000140001063 49C7C00A000000             mov r8, 0xa
 ; .text:000000014000106a FF1538110000               call qword ptr [_i64toa]
 ; .text:000000014000106a
 ; .text:0000000140001070 49C7C100000000             mov r9, 0x0
 ; .text:0000000140001077 4C8B053C100000             mov r8, qword ptr [0x1400020ba]
 ; .text:000000014000107e 488B1522100000             mov rdx, qword ptr [0x1400020a7]
 ; .text:0000000140001085 4833C9                     xor rcx, rcx
 ; .text:0000000140001088 FF150A110000               call qword ptr [MessageBoxA]
 ; .text:0000000140001088
 ; .text:000000014000108e 4883C408                   add rsp, 8
 ; .text:0000000140001092 C3                         ret
 ; sub_140001055   endp
 ; 
 ; ; --------------------------------------------------------------------------
 ; ; sub_140001093
 ; ; --------------------------------------------------------------------------
 ; sub_140001093   proc
 ; .text:0000000140001093 C8800000                   enter 0x80, 0x0
 ; .text:0000000140001097 4883EC60                   sub rsp, 0x60
 ; .text:000000014000109b 488BC9                     mov rcx, rcx
 ; .text:000000014000109e 488B151D100000             mov rdx, qword ptr [0x1400020c2]
 ; .text:00000001400010a5 49C7C00A000000             mov r8, 0xa
 ; .text:00000001400010ac FF15F6100000               call qword ptr [_i64toa]
 ; .text:00000001400010ac
 ; .text:00000001400010b2 49C7C100000000             mov r9, 0x0
 ; .text:00000001400010b9 4C8B051B100000             mov r8, qword ptr [0x1400020db]
 ; .text:00000001400010c0 488B15FB0F0000             mov rdx, qword ptr [0x1400020c2]
 ; .text:00000001400010c7 4833C9                     xor rcx, rcx
 ; .text:00000001400010ca FF15C8100000               call qword ptr [MessageBoxA]
 ; .text:00000001400010ca
 ; .text:00000001400010d0 C9                         leave
 ; .text:00000001400010d1 C3                         ret
 ; sub_140001093   endp
 ;
 ; ; --------------------------------------------------------------------------
 ; ; sub_1400010d2
 ; ; --------------------------------------------------------------------------
 ; sub_1400010d2   proc
 ; .text:00000001400010d2 55                         push rbp
 ; .text:00000001400010d3 488BEC                     mov rbp, rsp
 ; .text:00000001400010d6 4881EC80000000             sub rsp, 0x80
 ; .text:00000001400010dd 488BC9                     mov rcx, rcx
 ; .text:00000001400010e0 488B15FC0F0000             mov rdx, qword ptr [0x1400020e3]
 ; .text:00000001400010e7 49C7C00A000000             mov r8, 0xa
 ; .text:00000001400010ee FF15B4100000               call qword ptr [_i64toa]
 ; .text:00000001400010ee
 ; .text:00000001400010f4 49C7C100000000             mov r9, 0x0
 ; .text:00000001400010fb 4C8B05FC0F0000             mov r8, qword ptr [0x1400020fe]
 ; .text:0000000140001102 488B15DA0F0000             mov rdx, qword ptr [0x1400020e3]
 ; .text:0000000140001109 4833C9                     xor rcx, rcx
 ; .text:000000014000110c FF1586100000               call qword ptr [MessageBoxA]
 ; .text:000000014000110c
 ; .text:0000000140001112 C9                         leave
 ; .text:0000000140001113 C3                         ret
 ; sub_1400010d2   endp
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

TimoVJL

  • Member
  • ***
  • Posts: 476
Re: First time UASM 2.49 user noob question about 32-bit vs 64-bit
« Reply #17 on: September 22, 2019, 05:07:03 PM »
BTW I just saw the UASM COMDAT support -- this is a wonderful feature and it works great.
ml64 have -Gy for that, from version 12
May the source be with you

AW

  • Member
  • *****
  • Posts: 2442
  • Let's Make ASM Great Again!
Re: First time UASM 2.49 user noob question about 32-bit vs 64-bit
« Reply #18 on: September 22, 2019, 05:36:20 PM »
Hi Hutch,

You are doing a fantastic work on MASM 64-bit, which was delivered to the masses as a diamond in rough.
A lot of things can be done with macros (but others are impossible, such as producing the vectorcall calling convention), but in particular the asmguru requirement for direct loading of parameters into registers is a piece of cake with macros.
My point was actually that, there is no justification for demanding an Assembler to do everything ex-factory. Although Masm is too brute and Uasm is a little more polished, we can always work though macros or by hand like an artisan when what we search for is not delivered. People that want everything at their disposal, without further trouble, better search for a HLL.

asmguru

  • Regular Member
  • *
  • Posts: 5
Re: First time UASM 2.49 user noob question about 32-bit vs 64-bit
« Reply #19 on: September 24, 2019, 03:16:41 AM »
ml64 have -Gy for that, from version 12
Thank you, I didn't know that.

johnsa

  • Member
  • ****
  • Posts: 791
    • Uasm
Re: First time UASM 2.49 user noob question about 32-bit vs 64-bit
« Reply #20 on: October 02, 2019, 07:16:46 PM »
Hi,

If you want "naked" procedures I'd recommend just using the registers directly.

So, if you use:

Code: [Select]
option stackbase:rsp
option win64:15

for example firstly rbp is freed up and stack-frames are based on RSP instead. In addition you can declare a proc with named arguments (for type checking and invoke etc)

Code: [Select]
MyProc PROC FRAME aPtr:QWORD, aVal:DWORD

    ret
MyProc ENDP

Now you have several options:
1) Use the arguments by name.. this will trigger the allocation and setup of homing area for the parameter and it will be accessed from it's stack location
2) Ignore the argument name and just use the register directly in which case UASM optimise out the setup of the stack-frame (as it only does that for parameters that are actually referenced by name in the proc).
3) Use option proc:none or option prologue/epilogue to setup a completely manual procedure with no automatic intervention by the assembler.

For me I normally stick to (1) and for leaf functions where you're trying to get every last cycle I'd opt for (2) as it's still clean with less potential for mistakes.

If you're trying to keep those leaf functions more readable (hence why you'd want to still refer to named parameters) you could just setup some equates,

Code: [Select]
MyProc PROC FRAME aPtr:QWORD, aVal:DWORD

    _aPtr EQU <rcx>
    _aVal EQU <edx>

   mov rsi,_aPtr

    ret
MyProc ENDP

Something like that, which would also give you the ability to swap the text equate between param name and register ..