0

我是 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 通常在retlike之前释放堆栈

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, %edxfoo方法中?不应该movl $3, -12(%rsp)吗?这可能是我没有参考的原因foo_a.z之一main,但我也没有参考foo_a.ymain指令仍然是movl $2, -16(%rsp)

4

0 回答 0