Author Topic: stack alignment  (Read 33038 times)

Offline dtroyx

  • Jr. Member
  • *
  • Posts: 2
stack alignment
« on: July 01, 2010, 10:02:37 AM »
Hi

I'm new to ASM and I've read a lot about stack alignment. But I'm not sure I understand it correctly. This is how I understand it:

bytes you don't really need to align (every address is a correct alignment), words you must put on even addresses, double words must be on multiple of 4 addresses and quad words on multiple of 8's. When you are using SSE instructions you must align on 16 byte addresses.

so now a few examples:
If you want to allocate 10 bytes (for example a char array of 10), you can just do:
Code: [Select]
SUB esp, 10
If you want to allocate space on the stack for a double word, and the esp register contains 0FFF3h, then you first need to align it to an address that is a multiple of 4 and the resulting code should be:
Code: [Select]
SUB esp, 7we reduce it with 3 so the address in esp is a multiple of 4, then we reduce it with 4 to allocate the space for the double word, so in total we need to reduce the esp with 7.

Am I understanding it correctly? Because some tutorials says that you should always align on 4 byte addresses (even if you only need a byte), others says you should always align on 16 byte (but the 16 byte is only for SSE instructions right? So if you aren't going to use them, the 16 byte alignment isn't necessary?) and others don't even mention stack alignment.

Sorry if my English isn't very good, but I hope you understand my question.

Regards,
Philip

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: stack alignment
« Reply #1 on: July 01, 2010, 01:46:40 PM »
Hi Philip,

Good question! (Your English is perfect, BTW... but the CPU doesn't speak English anyway)

Quote
bytes you don't really need to align (every address is a correct alignment), words you must put on even addresses, double words must be on multiple of 4 addresses and quad words on multiple of 8's. When you are using SSE instructions you must align on 16 byte addresses.

This is generally true of variables anywhere in memory - not just the stack. Up to SSE, there is merely a performance penalty for unaligned access - apparently "not too bad". In the case of SSE, there are instructions which will tolerate unaligned addresses, and faster ones which will segfault if not aligned on 16 byte boundaries.

When it comes to the stack, my understanding is that it should (must?) be aligned at least on "stacksize" boundaries - 4 bytes for a 32-bit machine. So "sub esp, 10" would probably not be a good idea, even if all you need is 10 bytes - better to bump it up to "sub esp, 16". I observe that gcc seems always to align the stack to 16 bytes, regardless of the size of local variables, and regardless of whether SSE is actually being used.

There's some discussion of this issue in news:comp.lang.asm.x86 entitled "aligning to word boundaries" starting on 6/15/10, if you have access to newsgroups. (groups.google.com if you don't) Apparently the "real" read/write size is a cache line (32 bytes? 64 bytes?)

Agner Fog has written a nice document on optimization, which should cover this issue, among others:

http://www.agner.org/optimize/optimizing_assembly.pdf

IMO, a beginner should worry about making it "work" first, and worry about optimization later - but it won't hurt to develop good habits from the beginning!

Best,
Frank


Offline dtroyx

  • Jr. Member
  • *
  • Posts: 2
Re: stack alignment
« Reply #2 on: July 01, 2010, 02:53:50 PM »
Thanks for the response. And thank you for the document and newsgroup.

It's true I should more worry about getting everything to work, but I've read a lot about this issue and I wanted to know more about it and be sure that I understand it.

Regards
Philip

Offline c051n3

  • Jr. Member
  • *
  • Posts: 22
Re: stack alignment
« Reply #3 on: July 01, 2010, 07:41:21 PM »
The following is a good link from Microsoft regarding stack alignment:

http://msdn.microsoft.com/en-us/library/aa290049%28VS.71%29.aspx