Author Topic: equ vs equ <>  (Read 600 times)

Biterider

  • Member
  • ****
  • Posts: 545
  • ObjAsm Developer
    • ObjAsm
equ vs equ <>
« on: January 07, 2020, 03:26:47 AM »
Hi
Today I stumped on a strange behaviour of "equ". The code looks like

Code: [Select]
.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:
Code: [Select]
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

  • Member
  • *****
  • Posts: 1225
    • uasm
Re: equ vs equ <>
« Reply #1 on: January 07, 2020, 10:47:37 AM »
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

Code: [Select]
.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

Code: [Select]
/* 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 */
};

« Last Edit: January 07, 2020, 01:39:37 PM by habran »
Cod-Father

Biterider

  • Member
  • ****
  • Posts: 545
  • ObjAsm Developer
    • ObjAsm
Re: equ vs equ <>
« Reply #2 on: January 07, 2020, 09:18:46 PM »
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.
Code: [Select]
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
Code: [Select]
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

Quote
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
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