70,020
社区成员




struct data_st{
int a,b;
struct data_st *pnext;
};
int add_X(struct data_st data)
{
int a,b,c;
data.a = 10;
data.b = 5;
data.pnext = &data;
a = 1;
b = 2;
c = 3;
return 30001;
}
void call_X(void)
{
struct data_st data;
add_X(data);
}
int main()
{
int a = 0;
call_X();
return 0;
}
.file "test.c"
.text
.globl add_X
.type add_X, @function
add_X: #疑问三,这里咋没有sub ? 直接就那bp进行取数据了?
pushq %rbp
movq %rsp, %rbp
movq %rdi, %rax
movq %rsi, %rcx
movq %rcx, %rdx
movq %rax, -32(%rbp)
movq %rdx, -24(%rbp)
movl $10, -32(%rbp)
movl $5, -28(%rbp)
leaq -32(%rbp), %rax
movq %rax, -24(%rbp)
movl $1, -12(%rbp)
movl $2, -8(%rbp)
movl $3, -4(%rbp)
movl $30001, %eax
popq %rbp
ret
.size add_X, .-add_X
.globl call_X
.type call_X, @function
call_X:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp 疑问二,同疑问一,应该是12呀?
movq -16(%rbp), %rdx
movq -8(%rbp), %rax
movq %rdx, %rdi
movq %rax, %rsi
call add_X
leave
ret
.size call_X, .-call_X
.globl main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp #疑问1,这里为啥要减去16 ?而不是 4? a的size是4呀?
movl $0, -4(%rbp)
call call_X
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
pushq %rbp
上面这句的目的是因为下面这句要使用bp,所以先保存一下
movq %rsp, %rbp
上面这句是保存sp到bp中,由于push操作会改变sp, 所以保存sp只能用move语句
保存sp的目的是函数中的局部变量都保存在栈上,有新的变量定义sp的值就会改变,
sp的原始值保存在bp中,这样函数结束时释放线变量只需令sp = bp即可。
subq $16, %rsp
然而为了效率,并不是定义几个变量就对sp减几次,而是一次性分配一定空间。
改变sp的目的是为了让里层的函数以最新的sp为基址,所以最里层的函数就不需要改变sp了.
还有一点蛮奇怪的,函数开头有保存bp, sp函数结束时没有还原。
只有最里层函数用pop bp, 但貌似bp根本没变。
我猜测可能调用函数在父函数的最后一句,所以就不需要了