flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > A couple of extensions to existing macros. Suggestion.

Author
Thread Post new topic Reply to topic
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
In a parallel topic I saw, that Tomasz Grysztar was going to accomplish some modifications of a standard macro. Thus using this occasion I'd like to make a humble request for including some quite simple but useful features for existing standard macros.

1) The macro locals which is defined by the macro proc could redefine the align-directive with something like this:
Code:
macro align value { rb (value-1)-($-$$+value-1) mod value }    

This macro differs very little from what is provided by the manual, but this difference makes this macro only useful within the local variables definition. So it does not make much sense to define it somewhere else, however I think it's obvious why this modification is pretty useful exactly within local variables definition.

2) The macro proc itself could also define a macro statics similarly to the macro locals. I've already seen the macros iglobal/uglobal/IncludeIGlobals/IncludeUGlobals from freshlib which do the thing, but their main disadvantage is that the defined symbols are not local to procedure namespace scope and may correlate between different procedures which can become critical in large projects. I also don't like splitting variables declaration to iglobal and uglobal. It should be a single block (like globals or statics), where both initialized and uninitialized variables can be declared. However I'm not really sure about this, because some alignment problems may arise. But anyway splitting variables definition to IncludeIGlobals/IncludeUGlobals (or IncludeIStatics/IncludeUStatics by analogy) is surely reasonable and should be preserved.

3) The macro struct could take one more optional parameter, which defines alignment of the structure members with same alignment rules as #pragma pack(push, n) uses. The current behaviour of the struct macro should be the default behaviour (in case the optional alignment parameter is omitted). This modification would simplify the translation of some standard structures from c to fasm.
Post 06 Oct 2011, 21:07
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7721
Location: Kraków, Poland
Tomasz Grysztar
For 1) I would not decide to use such a simple macro solution, because it would loose the reliability ALIGN directive provides because it knows what the alignment of current address space (section, for instance) is. So macro should at least take into consideration what is the assumed alignment of virtual space in which it operates (stack frame in this case), to disallow alignments that would not be possible to provide (like "align 32").

Also: generally, when speaking about extending standard macro package, I like to point people to community fasm packaging project, but unfortunately it lacks good management and appears dead.
Post 06 Oct 2011, 21:16
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
Tomasz Grysztar
Quote:
I would not decide to use such a simple macro solution

I agree, this macro should be more complicated, and to implement it in a reliable way would require applying some changes on other macros used by the proc macro. My mistake. I considered only problems I had, writing following kind of code:
Code:
locals
        data SOME_ODD_SIZED_STRUCTURE <>
      dwUnalignedVal dd ?
endl    

Unaligned stack accesses, as such, are not quite wishful, but tolerable. However it becomes fairly irritating when passing a pointer to dwUnalignedVal to some WinApi function, that has a bad habit to return something like ERROR_ACCESS_DENIED in such a case.
Quote:
to disallow alignments that would not be possible to provide (like "align 32")

I actually don't understand, why it's not possible to make align 32. Back to assembly level it would look like
Code:
sub esp,sizeof.variable
and esp, not (value-1)    

for any value of power of two.
I don't mean, that it would be a good practice to generate this code for every align-directive within local variables declaration block. A better way would definitely be to take into account all of the alignments and variable sizes, when calculating localbytes and then make a single use of an aligning code. And the ebp-relative labels can be defined afterwards according to the corresponding alignment values of the local variables and the derived value of localbytes. Thus it seems to me, that any alignment is possible.

Quote:
generally, when speaking about extending standard macro package, I like to point people to community fasm packaging project

Well... I've already seen that. And exactly due to the fact, that this idea appears to have lost its viability, I decided to leave here a couple of likely good and comparatively easy achievable ideas as the only way to get them embedded into the official fasm package.

If you don't have any time for this, then just forget it. Smile
Post 06 Oct 2011, 22:50
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7721
Location: Kraków, Poland
Tomasz Grysztar
Oh, of course, you are right - by generating appropriate code locals can provide any alignment you want. And since locals already can sometimes generate additional code - when you initialize them with values, this would not be something unprecedented and appears to be the right solution. I will try to implement it when I find some spare time.
Post 07 Oct 2011, 13:50
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
Tomasz Grysztar
There's a little trade off when making assumptions about initial stack alignment.

If you assume the stack to be already aligned to 16/32/64 bit (depending on current code generation mode), then you don't need to generate additional alignment code regardless of the number and positions of align 2/4/8 within the locals block, which is an advantage of such assumption. However since this assumption is theoretically not always true, this will affect the align macro reliability, which is a disadvantage.

Thus even though the solution would become a little bit uglier, it seems to be the best idea to add an optional parameter to the locals macro, which provides information about what assumptions can be made about current stack alignment or at least a boolean value, allowing to make such assumption on the basis of code generation mode as follows:
Code:
macro detectMode byteCount
{
 virtual
             times 3 xchg ax,ax
          times 2 xchg eax,eax
                byteCount = ($-$$-6)*2
      end virtual
}    


P.S. I also think, it would make sense to restrict the alignment argument values of the align macro to the powers of two, making for example any other value to get rounded down to the nearest power of two.
Post 07 Oct 2011, 15:36
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode
Tomasz Grysztar wrote:
For 1) I would not decide to use such a simple macro solution, because it would loose the reliability ALIGN directive provides because it knows what the alignment of current address space (section, for instance) is.

Hi All,
i agree; and that address space comes to be asssumed, even when mounting the struc on a register.
but, just because of this, that anyway works correctly as in
Code:
 virtual at rbx
   struc A {
    .p1 db ?
   align 8
    .p2 dq ?
 }
end virtual
  a A
    
now considering that
Code:
 struc B {
   .p1 db ?
  align 8
  .p2 dq ?
 }
virtual at rbx
  b B
end virtual
    
generates error: section is not aligned enough.
i would turn it eventually to a warning and suggest that the use of following working solution
Code:
 virtual at rbx
struc C [data]{
  data
}
end virtual
 c C .p1 db ?,align 8,.p2 dq ?
    
as an "inlinining" form of definition, would be deprecated.
in fact, it is the confirmation that the struc directive
should only define structures, i.e memory
layouts; it should be virtual and its layout known
by default, i.e. something like
Code:
 struc E {
   .p1 byte ?
  align 8
  .p2 qword ?
 }
    
and
1) the following code knows E
2) i dont need to instantiate it by E E.
3) the STRUCT macro is no more required.

because we have always the opportunity to write
the structure explicitedly while instantiating it normally
Code:
  A:
 .p1 db ?
 align 8
 .p2 dq ?
    


or virtually at that address space
Code:
 virtual at punky
 A:
 .p1 db ?
 align 8
 .p2 dq ?
end virtual
    

Cheers,
Very Happy

_________________
⠓⠕⠏⠉⠕⠙⠑
Post 09 Nov 2011, 09:32
View user's profile Send private message Visit poster's website 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-2020, Tomasz Grysztar.

Powered by rwasa.