x86 Assembly - Byte Accounting
My real issue with the assembly is that there are 88 bytes being allocated on the stack for the local variable(and something else possibly), but the buffer is only 64 bytes which for x86 should not need any padding. So why are there extra bytes lying about? (24 of them)
target.c ;; compiled with `gcc target.c` Code:
#include <string.h> Code:
080483e4 <func>: using: gcc 4.6.1 objdump 2.21.1.20110627 |
I think it has something to do with the way gcc optimizes the alignment of the stack.
see the -mpreferred-stack-boundary option in your gcc manual. |
An extra 8 bytes are for passing two parameters to strcpy.
The rest is a 16 byte alignment thing: The stack frame has eip and ebp plus 88 bytes, which is 96 total, so 16 byte alignment is maintained. The 16 byte alignment occurs just before eip is pushed in a call. So after ebp is pushed, it is 8 bytes off from aligned. The 8 bytes "wasted" above buff serve to make buff itself 16 byte aligned (I'm not sure why it should be) then the fact that those 8 bytes were wasted means another 8 bytes must be wasted to keep overall alignment. |
Not knowing where those extra bytes were coming from was annoying.
Thanks for the help, I guess it's one more thing gcc is doing that I am unaware of. Will have to add that to the list of flags to track. |
16 byte alignment of the stack frame is probably a good thing. Millgates provided the keyword needed to search for documentation and/or to modify the behavior.
I'm more curious about the 16 byte alignment of char buff[64] I wouldn't know where to look in gcc documentation for the discussion of why that happens. I believe ordinary scalar variables are aligned according to their size (a double is 8 byte aligned, an int is 4 byte aligned, a char is 1 byte aligned). So why/when does an array have stricter alignment than elements of the array need? Or have I misinterpreted one (B) of the three chunks of eight bytes? A) One is for parameters to strcpy. B) Another is either for alignment of buff or I'm confused C) The third is for alignment of the stack frame only because of the second. |
Going back through the code more carefully, and now using the 16-byte alignment it makes more sense.
Here is how I'm reading it now; [----] := 4-bytes w := "wasted" bytes call pushes %eip to the indicated location [%eip][%ebp][wwww][wwww] [----][----][----][----] [----][----][----][----] [----][----][----][----] [----][----][----][---*] [wwww][wwww][*str][buff] then %ebp gets pushed to the stack, to make the array 16-byte aligned we need to subtract 0x40(char buff[64]) + 0x8(16-byte align stack from ebp and eip); we get the buffer at -0x48(array start location indicated by *). Then to maintain the 16-byte alignment for the 2 parameters to strcpy we need to subtract another 0x10 from the stack, thus the 0x58. Going through the function code the input address gets loaded to the location indicated by *str and the address for the array(*) gets loaded to the location indicated by buff. Code:
080483e4 <func>: Code:
080483fe <main>: So quite a bit of this is new to me. |
Quote:
|
All times are GMT -5. The time now is 07:14 PM. |