flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > problem defining data with "local" macro

Author
Thread Post new topic Reply to topic
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 20 Dec 2006, 21:59
I tried to define a "local txmm:DQWORD" inside a procedure and it gave me a "extra characters on line error", am I using the right define for an xmm0 register?
Post 20 Dec 2006, 21:59
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 20 Dec 2006, 22:41
Right, so it's just one more correction to macros in latest 1.67.17 package. Smile
Post 20 Dec 2006, 22:41
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 21 Dec 2006, 00:23
Great! Thanks.
Post 21 Dec 2006, 00:23
View user's profile Send private message Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 05 Jan 2007, 18:12
Um, this is more a request than a bug, but would it be possible to align DQWORD (xmm?) data on the stack to 16 bytes? And for that matter, mmx data to 8 bytes?
Post 05 Jan 2007, 18:12
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 05 Jan 2007, 20:35
like this?
Code:
locals
align 16
dq 0
endl    


but i agree for LOCAL macro, 8 and 16 byte data should be aligned
Post 05 Jan 2007, 20:35
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 05 Jan 2007, 21:42
Vid: tried your method but get an invalid value error. Confused

After thinking about it a bit more, I have to wonder if it's even possible?
the esp value would change each run of the executeable, and therefore alignment would be next to impossible to calculate?.
Post 05 Jan 2007, 21:42
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 05 Jan 2007, 22:29
BTW, is this possible with EBP-based frames? I found pretty hard aligning and keeping access to parameters (but on ESP-based frames EBP clould be dedicated for parameters access and ESP for local variables access).
Post 05 Jan 2007, 22:29
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 06 Jan 2007, 04:43
madmatt: you are right, i didn't realize that. but you still can do something like:

Code:
push ebp
mov ebp, esp
and ebp, not (16-1)  ;16 = highest needed alignment, can be also 8
sub esp, 1234    


you just need to tweak proc macros Razz
Post 06 Jan 2007, 04:43
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 06 Jan 2007, 05:20
vid, since proc uses EBP based frame I think that this is quite imposible, the padding will be of variable length but the offsets will not change on runtime, so things like:
Code:
mov eax, [parameter]    
Will produce a
Code:
mov eax, [ebp+fixedOffset]    
when actually it should be
Code:
mov eax, [ebp+fixedOffset+paddingSize]    


A solution to keep EBP-based frames could be modifying proc macros to signalize invoke/stdcall/ccall to perform correct alignment.

Example:

Code:
stdcall  exampleProc, 4, 6, 9

proc exampleProc stackAlignment:QWORD, arg1, arg2, arg3

  ret
endp    


The "dissasembling" of that is
Code:
; and esp, -7 ; I'd would like to use it but I have no idea of how to restore its original value...
sub esp, 4 ; ESP-4
push 9 ; ESP-8
push 6 ; ESP-12
push 4 ; ESP-16
call exampleProc ; ESP-20
add esp, 4

exampleProc:
push ebp ; ESP-24
mov ebp, esp ; Now we have a QWORD aligned ESP (24 mod 8 = 0)

leave
retn 12    


A possible solution but quite unoptimal could be relocating parameters after padding by moving them to the padding area.
Post 06 Jan 2007, 05:20
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 06 Jan 2007, 08:39
sorry, i'm ill now, my thinking is kinda slowed down
Embarassed
Post 06 Jan 2007, 08:39
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 06 Jan 2007, 15:33
I checked IA-32 Intel® Architecture Optimization the Appendix D Stack Alignment, I don't like what I saw... It needs EBX so it's simple unnaceptable (for me at least).

Note that I was wrong about moving to the padding area because I forgot that between local variables and parameter exists something called return address so doing such movement will overwrite it... (unless of course that the total length of the parameters are less than the padding size). For that reason actually we need to assign some space in the stack frame and copy all parameters to it (so the stack will have two copies of the parameters).

The other alternative (which I like a little more) is leaving the resposability of aligning the stack to the caller in this way:

1- If invoke/stdcall/ccall is called from a non proc context then is resposability of the programmer to preserve ESP in some way.
2- If invoke/stdcall/ccall is called from a proc context then the proc macro will redefine invoke/stdcall/ccall with a special code that will do "mov [ebp+secretESPSaveArea], esp" and proc macro of course will define such local variable if it detects that there was some call to a proc with stackAlignment option.

So here an example of case 2

Code:
proc a
  stdcall b, 1, 2, 3
  ret
endp
proc b arg1, arg2, arg3

ret
endp
    


The "dissasembling":
Code:
a:
push ebp
mov ebp, esp
sub esp, 4 ; Space for secretESPSaveArea

mov [ebp+secretESPSaveArea], esp
and esp, -8
sub esp, 4 ; (total size of parameters[12] + return address size[4] + callee's EBP save area[4]) mod 8
push 3
push 2
push 1
call b
mov esp, [ebp+secretESPSaveArea]

leave
ret

b:
push ebp
mov ebp, esp
; sub esp, 4 ; Space for secretESPSaveArea (Not this time since b does not call anything needing stack alignment)

leave
retn 12    
Post 06 Jan 2007, 15:33
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 06 Jan 2007, 19:25
Forget secretESPSaveArea, it is really stupid specially when we have an alternative which is context independent...

This is my new alternative
Code:
mov edx, esp ; Since "addr" destroys EDX I take the license to do the same
and esp, -8 ; for QWORD alignment; -16 for DQWORD alignment; -4 for DWORD alignment (typicaly unneded since stack looses its DWORD aligning on very few and unconventional situations like push reg16)
sub esp, (espSaveArea+totalSizeOfParamenters+returnAddressSize+CalleeEBPSaveArea) mod alignmentSize
push edx
push allParams
call procedure
pop esp    
Post 06 Jan 2007, 19:25
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 06 Jan 2007, 23:04
Code:
; ### DON'T USE THE MACROS BELOW
macro PrepareStack alignment, paramsSize
{ 
  mov     edx, esp ; Since "addr" destroys EDX I take the license to do the same 
  and     esp, -alignment
  if      ((paramsSize+12) mod alignment) > 0
    sub     esp, alignment - ((paramsSize+12) mod alignment)
  end if
  push    edx 
}

macro CalculateParamsSize outResult, [params]
{
common
  outResult = 0
forward
  if params ~eq
    outResult = outResult + 4
    match =double param, params\{outResult = outResult + 4\}
  end if
}

macro DoCall callType, proc, [params]
{
common
local paramsSize

  if defined proc#.stackAlignment
    CalculateParamsSize paramsSize, params
    PrepareStack proc#.stackAlignment, paramsSize
    callType proc, params
    pop      esp
  else
    callType proc, params
  end if
}


;### ONLY USE THE MACROS BELOW

macro SetStackAlignment procName, alignType
{
local stackAlignment

  stackAlignment = 0
  match =DWORD,  alignType\{stackAlignment =  4\}
  match =QWORD,  alignType\{stackAlignment =  8\}
  match =DQWORD, alignType\{stackAlignment = 16\}

  if ~stackAlignment
    display `alignType," is not a valid alignment"
    err
  end if

  procName#.stackAlignment = stackAlignment
}

macro invoke proc, [params]
{
common
  DoCall invoke, proc, params
}

macro cinvoke proc, [params]
{
common
  DoCall cinvoke, proc, params
}

macro stdcall proc, [params]
{
common
  DoCall stdcall, proc, params
}

macro ccall proc, [params]
{
common
  DoCall ccall, proc, params
}    


In any place use SetStackAlignment procName, {DWORD|QWORD|DQWORD}

I tested it a little so more testings are welcome Very Happy

Cheers

PS: BTW, http://board.flatassembler.net/topic.php?p=50905#50905 is still a good feature to have since my macros just aligns EBP but that doesn't prevent you from unalign local data, for example
Code:
locals
  character: BYTE
  sseData: DQWORD ; Unaligned even with my macros
ends    


But this feature will require a built in proc SetStackAlignment feature to inform to "align" up to which number the alignment can be made.


Last edited by LocoDelAssembly on 07 Jan 2007, 00:24; edited 3 times in total
Post 06 Jan 2007, 23:04
View user's profile Send private message Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 06 Jan 2007, 23:08
I've found a solution that is simple Cool , and am wondering why I didn't think of it before Surprised . This will also allow arrays of DQWORDS as well. Smile

Code:
     
proc SomeProc
     local aligned_address:DWORD, xmmdata:[(NUMBER_OF_DQWORDS * 16) + 16]

     lea     eax, [xmmdata]
     and     eax, $fffffff0
     add     eax, 16
     mov     [aligned_address], eax
     .....more code
endp
    
Exclamation
Post 06 Jan 2007, 23:08
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 07 Jan 2007, 00:35
I did some bugs corrections. Using your example I did the following test that runs flawlessly

Code:
format pe gui
include 'win32axp.inc'
include 'stackAlignment.inc' ; The macros posted previously

NUMBER_OF_DQWORDS equ 8

dec esp ;guaranteed odd number
stdcall SomeProc
inc esp
ret

proc SomeProc
local xmmdata[NUMBER_OF_DQWORDS]:DQWORD
  SetStackAlignment SomeProc, DQWORD

  match count, NUMBER_OF_DQWORDS
  {
    rept count i:0, NUMBER_OF_DQWORDS\{movdqa xmm\#i, [xmmdata+16*i]\}
  }
  ret
endp
    


The dissasembling of all that (with the assistance of OllyDbg Razz) is:
Code:
dec esp

mov edx, esp
and esp, -16
sub esp, 4
push edx
call SomeProc
pop esp

inc esp
retn

SomeProc:
push ebp
mov ebp, esp
sub esp, $80
movdqa xmm0, [ebp-80]
movdqa xmm1, [ebp-70]
movdqa xmm2, [ebp-60]
movdqa xmm3, [ebp-50]
movdqa xmm4, [ebp-40]
movdqa xmm5, [ebp-30]
movdqa xmm6, [ebp-20]
movdqa xmm7, [ebp-10]
leave
retn    

Without the macros the program crashes inmediately of course since movdqa requires aligned addresses.
Post 07 Jan 2007, 00:35
View user's profile Send private message Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 07 Jan 2007, 07:01
Making it a little bit simpler, thanks to locodelassembly:
Code:
proc SomeProc 
     local aligned_address:DWORD, xmmdata[NUMBER_OF_DQWORDS + 1]:DQWORD 

     lea     eax, [xmmdata] 
     and     eax, $fffffff0 
     add     eax, 16 
     mov     [aligned_address], eax 
     .....more code 
endp    
Post 07 Jan 2007, 07:01
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.