home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.asm.x86      Ahh, the lost art of x86 assembly      4,675 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 2,980 of 4,675   
   Bernhard Schornak to Bartc   
   Re: 64 bit stack alignment   
   30 Aug 17 17:49:32   
   
   From: schornak@nospicedham.web.de   
      
   Bartc wrote:   
      
      
   > On 30/08/2017 10:10, Bernhard Schornak wrote:   
   >> Alex wrote:   
   >   
   >>> It seems to be the only way of doing this without branches, flags or other   
   expensive nonsense. But,   
   >>> as ever, there may be a better way. Any suggestions?   
   >>   
   >>   
   >> If we assume the stack was properly aligned by the calling function,   
   >> there is only one way to align the stack while your function code is   
   >> running:   
   >>   
   >>   
   >> sub $0x?8, %rsp   
   >> ...   
   >> function code   
   >> ...   
   >> add $0x?8, %rsp   
   >> ret   
   >>   
   >>   
   >> The subtracted space must be at least 32 (0x20) byte for microsoft's   
   >> 'red zone' plus 8 byte for the return address (pushed onto the stack   
   >> by the calling function!), so a 'leaf function' should subtract 0x28   
   >> to work properly in a multithreaded environment. This subtraction of   
   >> 40 (0x28) automatically aligns your stack if it was properly aligned   
   >> before. Add as many paragraphs (0x28 + n*16 byte) as required as the   
   >> local storage for your function.   
   >   
   > This assumes the code doesn't use the stack for any other purposes between   
   function entry, and a   
   > call to a function that expects the stack to be aligned (at the call).   
   >   
   > For example, things may be put on the stack while evaluating a complex   
   expression and one of the   
   > terms requires a call. Or you are pushing arguments 5, 6 or 7 of a complex   
   call, and one of those   
   > expressions itself involves a function call.   
   >   
   > It is also possible, if not calling external functions, that calls to   
   internal functions in your   
   > code, which do not require alignment, do not bother with keeping the stack   
   aligned, or use a simple   
   > argument-passing convention (and have pushed an even or odd number of   
   parameters), or don't need a   
   > stack frame.   
   >   
   > For whatever reason, when it is necessary to call an external function, it   
   won't know the stack   
   > alignment.   
      
      
   What I wrote is working code following the rules MS defined for 64 bit   
   Windoze. Whatever your code does: The stack bottom (content of RSP) is   
   the border between the currently executed code and other code snippets   
   belonging to the same process. 'New' code only will access stack above   
   RSP if it belongs to a passed structure (which should return some data   
   requested by the caller) or if more than 4 parameters were passed (the   
   5th up to the last parameter are passed at the dwords 0x20[RSP] + size   
   of stack frame (e.g. 0x48[RSP] if you subtracted 0x28 in your function   
   entry sequence). Per definition, the so called 'red zone' at the stack   
   bottom (here 0x28...0x47[RSP] after subtracting 0x28 from RSP) belongs   
   to the called function and can be used as local storage by the callee.   
      
   If no function violates the convention (and working MS code definitely   
   obeys all rules), the stack cannot be misaligned. Only faulty function   
   entry code is capable to move RSP outside paragraph boundaries.   
      
      
   > (Solutions I've used:   
   >   
   > * Call a special stub function for calling external functions. There is a   
   separate one for 4, 5, 6   
   > etc parameters. It uses a check, and branch, and will rearrange things as   
   needed. It expects such   
   > calls to be rare. Local calls use a private call convention.   
   >   
   > * Keep track of how many things have been pushed onto the stack at any point   
   in an instruction   
   > sequence. Then it will know if the stack is aligned or not and generate the   
   correct code.   
   >   
   > * Avoid using the stack for any purpose than for calling functions. And in   
   the latter case, it   
   > avoids nested calls (by pre-evaluating any such terms). Both the last two   
   I've used in generated code.)   
      
      
   On modern machines, it is a bad idea to push and pop data onto or from   
   the stack, because this needs an additional register (generally RBP is   
   used as so called base pointer). None of my programs uses PUSH/POP. It   
   only is useful for very low level stuff (like retrieving th content of   
   RIP). Using wrappers (your 'stubs'):   
      
   http://st-intelligentdesign.blogspot.de/2010/11/st-opens-wrapper   
   -for-64-bit-windoze.html   
      
   The linked file provides wrappers for the most used functions provided   
   by the common Windoze libraries. The advantage of wrappers is a 'clean   
   environment', where registers don't lose their content while calling a   
   'dirty' C/C++/whatever-function clobbering registers without restoring   
   them on exit.   
      
   It shouldn't be a problem to translate AT&T-style assembler to iNTEL's   
   goobledigook... ;)   
      
      
   Greetings from Augsburg   
      
   Bernhard Schornak   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca