问题描述
我是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
分配了20个字节。对于大多数功能,gcc通常在ret
之前先取消分配栈,例如
somefunc:
subq $16,%rsp
...
addq $16,%rsp
ret
但是ret
中的foo
指令之前没有取消分配堆栈指令,为什么?编译器是否故意这样做,因为它释放了foo
的堆栈,那么我们无法将struc返回给函数?如果是出于这个目的,那么我就能理解为什么foo
中没有栈的重新分配。
Q2-似乎堆栈上foo_a
的内部结构是3|2|1
而不是1|2|3
,为什么编译器会以错误的方式处理问题?
为什么要在movl $3,%edx
方法中使用foo
?不应该是movl $3,-12(%rsp)
吗?可能是我没有在foo_a.z
中引用main
但在foo_a.y
中也没有引用main
且指令仍然是{{1}的原因之一}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)