我是 C 和汇编代码的新手,只是一个关于返回结构的问题,下面是我的代码
// c code
struct MyObj{
int x,y,z;
};
struct MyObj foo(){
struct MyObj foo_a;
foo_a.x = 1;
foo_a.y = 2;
foo_a.z = 3;
return foo_a;
}
int main () {
struct MyObj main_a = foo();
printf("value is %d\n", main_a.x);
return 0;
}
//assembly code
foo:
movl $1, -20(%rsp) //<----- allocate 20 bytes on the stack?
movl $2, -16(%rsp)
movq -20(%rsp), %rax
movl $3, %edx
ret
.LC0:
.string "value is %d\n"
main:
subq $24, %rsp // <----allocate 24 bytes on stack by decrementing stack pointer by 24
movl $0, %eax
call foo
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
addq $24, %rsp
ret
以下是我的问题:
Q1-您可以看到在foo
方法的堆栈中,它似乎为foo_a
. 对于大多数函数,gcc 通常在ret
like之前释放堆栈
somefunc:
subq $16, %rsp
...
addq $16, %rsp
ret
ret
但是in指令之前没有释放堆栈指令foo
,这是为什么呢?编译器是否故意这样做,因为如果它释放堆栈foo
然后我们无法将结构返回给函数?如果是为了这个目的,那我就可以理解为什么在foo
.
Q2-似乎foo_a
堆栈上的内部结构3|2|1
不是1|2|3
,为什么编译器会以错误的方式做事?
Q3-为什么movl $3, %edx
在foo
方法中?不应该movl $3, -12(%rsp)
吗?这可能是我没有参考的原因foo_a.z
之一main
,但我也没有参考foo_a.y
,main
指令仍然是movl $2, -16(%rsp)