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。这很奇怪,因为它使查找在线教程变得更加困难。