这是main的汇编代码:
push %rbp
mov %rsp,%rbp
sub $0x20,%rsp
mov %edi,-0x14(%rbp)
mov %rsi,-0x20(%rbp)
mov -0x20(%rbp),%rax
add $0x8,%rax
mov (%rax),%rax
mov %rax,%rdi
callq 0x510 <atoi@plt>
mov %eax,-0x4(%rbp)
mov -0x4(%rbp),%edx
mov -0x14(%rbp),%eax
mov %edx,%esi
mov %eax,%edi
callq 0x63a <sub>
leaveq
retq
这是C对应的代码:
#include <stdlib.h>
int sub(int x, int y){
return 2*x+y;
}
int main(int argc, char ** argv){
int a;
a = atoi(argv[1]);
return sub(argc,a);
}
我相信它将在堆栈中分配20位,然后将参数的值从右向左推入rbp-14和rbp-20,对吗?为什么需要20位?以及为什么将0x8添加到rax?
这里是带注释的版本:/建立一个堆栈框架。堆栈必须对齐以符合ABI,/所以尽管只需要2(* 8 = 16)个位置,但4个8字节(= 32)/位置已保留。推送%rbpmov%rsp,%rbpsub $ 0x20,%rsp
/ store away argc, argv for later.
mov %edi,-0x14(%rbp)
mov %rsi,-0x20(%rbp)
/ get the value of argv[1]: argv is a vector of char *, so
/ load argv:
mov -0x20(%rbp),%rax
/ index by 1:
add $0x8,%rax
/ load argv[1].
mov (%rax),%rax
/ copy into first parameter of atoi
mov %rax,%rdi
callq 0x510 <atoi@plt>
/ store the result
mov %eax,-0x4(%rbp)
/ load parameter 2 of sub:
mov -0x4(%rbp),%edx
/ load parameter 1 of sub (argc).
mov -0x14(%rbp),%eax
/ move parameters to abi parameter registers
mov %edx,%esi
mov %eax,%edi
callq 0x63a <sub>
/ remove stack frame for this function
leaveq
retq
此版本删除了冗余负载,为清楚起见进行存储:
push %rbp
mov %rsp,%rbp
sub $0x20,%rsp
mov %edi,-0x14(%rbp)
mov 8(%rsi), %rdi
callq 0x510 <atoi@plt>
mov %eax, %rsi
mov -0x14(%rbp), %rdi
callq 0x63a <sub>
leaveq
retq