0

gcc 如何决定为堆栈分配多少内存,为什么当我printf()从 main 中删除(或任何函数调用)时它不再减少 %rsp?

1.当我使用代码示例时,我注意到:https : 6th line//godbolt.org/z/fQqkNEsubq $48, %rsp如果我printf()从我的C代码中删除line 22. 看起来当我没有从我的 main 中进行任何函数调用时,%rsp它不会递减,但数据仍然会根据%rbp偏移量分配。我认为%rsp只有在堆栈增长时才会改变。我的理论是,由于它不会进行任何其他函数调用,它知道它不需要为其他不存在的函数保留堆栈。%rsp但是随着数据的保存,不应该继续增长吗?

2.向 my 中添加变量时rect struct,我还注意到它有时会以大于添加的数据类型大小的步长分配内存。在决定分配多少内存给堆栈时遵循什么约定?

3.有没有在线工具可以将汇编代码作为输入,然后绘制堆栈图像并告诉我每个寄存器在任何执行点的状态?Godbolt.org 是一个非常好的工具,我只希望它有这两个额外的功能。

我将粘贴下面的代码,以防将来godbolt的链接停止工作:

#include <stdio.h>
#include <stdint.h>
struct rect {
    int a;
    int b;
    int* c;
    int d[2];
    uint8_t f;
};

int main() {
    int arr[2] = {2, 3};
    struct rect Rect;
    Rect.a = 10;
    Rect.b = 20;
    Rect.c = arr;

    Rect.d[0] = Rect.a;
    Rect.d[1] = Rect.b;

    Rect.f =255;
    printf("%d and %d", Rect.a, Rect.b);

    return 0;
}
.LC0:
        .string "%d and %d"
main:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $48, %rsp
        movl    $2, -8(%rbp)
        movl    $3, -4(%rbp)
        movl    $10, -48(%rbp)
        movl    $20, -44(%rbp)
        leaq    -8(%rbp), %rax
        movq    %rax, -40(%rbp)
        movl    -48(%rbp), %eax
        movl    %eax, -32(%rbp)
        movl    -44(%rbp), %eax
        movl    %eax, -28(%rbp)
        movb    $-1, -24(%rbp)
        movl    -44(%rbp), %edx
        movl    -48(%rbp), %eax
        movl    %eax, %esi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        movl    $0, %eax
        leave
        ret

PS:我遵循的书使用 AT&T 语法来教授 x86。这很奇怪,因为它使查找在线教程变得更加困难。

4

0 回答 0