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