I've written a code snippet that stores a C++ object inside a char array wrapped in a struct, with the intent of passing it to a function written in C:
class cpp_type
{
public:
// ...
private:
int _state;
};
struct c_type
{ char buf[4]; };
struct c_type make_c_type()
{
c_type tmp;
new (tmp.buf) cpp_type();
return tmp;
}
Then I was curious how the compiler translates make_c_type
to x86_64
assembly code. GCC (with optimizations) produces:
0000000000000000 <_Z11make_c_typev>:
0: 48 83 ec 18 sub $0x18,%rsp
4: 48 8d 7c 24 0c lea 0xc(%rsp),%rdi
9: e8 00 00 00 00 call e <_Z11make_c_typev+0xe>
e: 8b 44 24 0c mov 0xc(%rsp),%eax
12: 48 83 c4 18 add $0x18,%rsp
16: c3 ret
I'm confused as to why the stack pointer is decremented by 24 bytes and rdi
set to rsp + 12
. The structure itself is only 4 bytes large, why doesn't GCC output e.g. sub $0x4,%rsp
followed by mov %rsp,%rdi
? Furthermore, shouldn't the stack always remain 16 byte aligned anyways?