TL;DR
When aligning the stack to multiple of 16 bytes, why are the paddings at the higher address for struct while at the lower address for primitive types?
More details
First of all, my machine follows System V AMD64 ABI, and I understand that the stack is aligned to 16 bytes. But when I try to understand how structs are stored on the stack, I found some interesting behavior of GCC that I don't understand.
I have the following program:
struct S {
long i;
};
void take_struct_addr(struct S *sp);
void take_long_addr(long *l);
void access_member() {
struct S s;
take_struct_addr(&s);
}
void access_local() {
long l;
take_long_addr(&l);
}
I compile it using the following command:
$ gcc -ansi -pedantic -S -Og access-member.c
And I get the following assembly code:
.file "access-member.c"
.text
.globl access_member
.type access_member, @function
access_member:
.LFB0:
.cfi_startproc
subq $24, %rsp
.cfi_def_cfa_offset 32
movq %rsp, %rdi # <---------- start address of the struct
call take_struct_addr
addq $24, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE0:
.size access_member, .-access_member
.globl access_local
.type access_local, @function
access_local:
.LFB1:
.cfi_startproc
subq $24, %rsp
.cfi_def_cfa_offset 32
leaq 8(%rsp), %rdi # <---------- start address of the long
call take_long_addr
addq $24, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE1:
.size access_local, .-access_local
.ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-39)"
.section .note.GNU-stack,"",@progbits
So, my question is why are the padding locations different in these two cases? Thanks in advance!