Lets's say we pass a struct to a fucntion as:
struct rect {
long llx;
long lly;
};
long test() {
struct rect oldRect;
oldRect.llx = 1;
oldRect.lly = 2;
struct rect newRect = make_double(oldRect);
return newRect.llx * newRect.lly;
}
struct rect make_double(struct rect r) {
r.llx *= 2;
r.lly *= 2;
return r;
}
To dig deeper what actually happen when passing a struct variable, I compiled C code into assembly as below shows:
// remove some directives that affects readibility
test:
subq $56, %rsp
movl $1, %edi
movl $2, %esi
call make_double
imulq %rdx, %rax
addq $56, %rsp
ret
make_double:
leaq (%rsi,%rsi), %rdx
leaq (%rdi,%rdi), %rax
ret
It is interesting to observe that, when passing the struct oldRect, the gcc actually copy its members into registers which will be used as arguments in make_double function. So my questions are:
Q1-Just to confirm that When passing a struct variable, the compiler will get the struct's all members and copy them to registers, is my understanding /observation correct?
Q2-Since the compiler allocated memory space for oldRect by decrementing stack pointer, but the compiler doesn't actually push 1 and 2 to oldRect.llx , oldRect.lly respectively, if this is the case, the compiler doesn't even need to decrement stack pointer in the first place?
Q3- I'm a little bit confused with this instruction:
subq $56, %rsp
why we have to decrement stack pointer by 56? the size of struct rect is 16, no padding is needed, so why it is not
subq $16, %rsp