News:

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

Main Menu

equ vs equ <>

Started by Biterider, January 07, 2020, 03:26:47 AM

Previous topic - Next topic

Biterider

Hi
Today I stumped on a strange behaviour of "equ". The code looks like


.xmm
option casemap:none
option dotname     
option frame:auto   
option win64:8     
option stackbase:rsp

.code

WinTest_Startup proc Arg1:QWORD
  ret
WinTest_Startup endp

WinStart equ WinTest_Startup

start proc
  invoke WinTest_Startup, 123
  invoke WinStart, 123
  ret
start endp

end start


and compiled with uasm64 2.49.0.2:
00007FF799371001 48 83 EC 28          sub         rsp,28h 
00007FF799371005 48 C7 C1 7B 00 00 00 mov         rcx,7Bh 
00007FF79937100C E8 EF FF FF FF       call        00007FF799371000 
00007FF799371011 6A 7B                push        7Bh 
00007FF799371013 E8 E8 FF FF FF       call        00007FF799371000 
00007FF799371018 48 83 C4 28          add         rsp,28h 
00007FF79937101C C3                   ret


You can see, that the second invoke can be performed without problems, but uasm seems to think that a different calling convention should be used.
If we replace the "equ" directive with "textequ"  or "equ <WinTest_Startup>", everthing will work again.

I think we have a "feature" here that needs some attention.

Biterider

habran

#1
Hi Biterider :biggrin:

If you use WinStart = WinTest_Startup instead of WinStart equ WinTest_Startup it will work
It will work as well if you use WinStart equ WinTest_Startup before .code section

In WinStart = WinTest_Startup equate sign is an assembly time directive and it uses different approach
In WinStart equ WinTest_Startup EQU is a Constant directive so if used inside .code, text must be inside <> brackets.
To get better idea how it works you can look up equate.c source in UASM folder


.xmm
option casemap:none
option dotname     
option frame:auto   
option win64:8     
option stackbase:rsp

WinStart equ WinTest_Startup

.code

WinTest_Startup proc Arg1:QWORD
  ret
WinTest_Startup endp


start proc
  invoke WinTest_Startup, 123
  invoke WinStart, 123
  ret
start endp

end start

If I recoil correctly,  we had discussion about EQU inside .code section long time ago somewhere in this forum
However, it is very interesting "feature" of UASM of which we have to be aware :smiley:
BTW I suggest to use option win64:11 instead of option win64:8
and if you want 16 byte data aligned use option win64:15


/* flags for win64_flags */
enum win64_flag_values {
    W64F_SAVEREGPARAMS = 0x01, /* 1=save register params in shadow space on proc entry */
    W64F_AUTOSTACKSP   = 0x02, /* 1=calculate required stack space for arguments of INVOKE */
    W64F_STACKALIGN16  = 0x04, /* 1=stack variables are 16-byte aligned; added in v2.12 */
    W64F_SMART         = 0x08, /* 1=takes care of everything */
    W64F_HABRAN = W64F_SAVEREGPARAMS | W64F_AUTOSTACKSP | W64F_SMART,
    W64F_ALL = W64F_SAVEREGPARAMS | W64F_AUTOSTACKSP | W64F_STACKALIGN16 | W64F_SMART, /* all valid flags */
};

Cod-Father

Biterider

Hi habran
Thanks for the clarification.
My point is, that it is a bit strange that you can use "equ" and make an invoke with the new symbol, but the calling convention changed.
I checked what happened using ML 6.15 in 32 bit. It accepts the code, compiles and executes correctly as expected.
option casemap:none                                     ;Case sensitive
option dotname                                          ;Enable dot names
.686p                                                   ;Use 686 protected mode
.model flat, stdcall   

.code

WinTest_Startup proc Arg1:DWORD
  ret
WinTest_Startup endp

WinStart equ WinTest_Startup
 
start proc
  invoke WinTest_Startup, 123
  invoke WinStart, 123
  ret
start endp

end start

00781000 55                   push        ebp 
00781001 8B EC                mov         ebp,esp 
00781003 C9                   leave 
00781004 C2 04 00             ret         4 
00781007 6A 7B                push        7Bh 
00781009 E8 F2 FF FF FF       call        00781000 
0078100E 6A 7B                push        7Bh 
00781010 E8 EB FF FF FF       call        00781000


QuoteBTW I suggest to use option win64:11 instead of option win64:8
and if you want 16 byte data aligned use option win64:15
Thank you very much. I have read the manual again and have now switched to win64: 15.
I was wrong in believing that "W64F_SMART = 0x08, // 1 = takes care of everything (Uasm)" really takes care of everything :cool:

Regards, Biterider