; 参数>=7时
Func(a, b, c, d, e, f, g, h);
;参数的具体存放方式
a->%rdi, b->%rsi, c->%rdx, d->%rcx, e->%r8, f->%r9
h->8(%esp)
g->(%esp)
call Func
1. 函数调用
... ;参数压栈
call Func ;将返回地址压栈,并跳转到子函数处执行
... ;函数调用的返回位置
Func: ;子函数入口
pushq %rbp ;保存父函数的帧指针,创建新栈帧
movq %rsp, %rbp ;让 %rbp 指向新栈帧的起始位置
subq $N, %rsp ;开辟栈帧空间供子程序使用
2. 函数返回
movq %rbp, %rsp ; 使 %rsp 和 %rbp 指向同一位置,即子栈帧的起始处, 收回子栈帧空间
popq %rbp ; 将栈中保存的父栈帧的 %rbp 的值赋值给 %rbp,并且 %rsp 上移一个位置指向父栈帧的结尾处
int add(int a, int b, int c, int d, int e, int f, int g, int h) { // 8 个参数
int sum = a + b + c + d + e + f + g + h; //相加求和
return sum;
}
int main(void) {
int i = 10;
int j = 20;
int k = i + j;
int sum = add(11, 22,33, 44, 55, 66, 77, 88);
int m = k; // 为了观察 %rax Caller Save 寄存器的恢复
return 0;
}
add:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
movl %edx, -28(%rbp)
movl %ecx, -32(%rbp)
movl %r8d, -36(%rbp)
movl %r9d, -40(%rbp)
movl -24(%rbp), %eax
addl -20(%rbp), %eax
addl -28(%rbp), %eax
addl -32(%rbp), %eax
addl -36(%rbp), %eax
addl -40(%rbp), %eax
addl 16(%rbp), %eax
addl 24(%rbp), %eax
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
leave
ret
main:
.LFB3:
pushq %rbp
.LCFI2:
movq %rsp, %rbp
.LCFI3:
subq $48, %rsp
.LCFI4:
movl $10, -20(%rbp)
movl $20, -16(%rbp)
movl -16(%rbp), %eax
addl -20(%rbp), %eax
movl %eax, -12(%rbp)
movl $88, 8(%rsp)
movl $77, (%rsp)
movl $66, %r9d
movl $55, %r8d
movl $44, %ecx
movl $33, %edx
movl $22, %esi
movl $11, %edi
call add
movl %eax, -8(%rbp)
movl -12(%rbp), %eax
movl %eax, -4(%rbp)
movl $0, %eax
leave
ret
.LFB3:
pushq %rbp
.LCFI2:
movq %rsp, %rbp
.LCFI3:
subq $48, %rsp
movl $10, -20(%rbp)
movl $20, -16(%rbp)
movl -16(%rbp), %eax
addl -20(%rbp), %eax
movl %eax, -12(%rbp)
movl $88, 8(%rsp)
movl $77, (%rsp)
movl $66, %r9d
movl $55, %r8d
movl $44, %ecx
movl $33, %edx
movl $22, %esi
movl $11, %edi
call add
add:
.LFB2:
pushq %rbp ; 保存父栈帧指针
.LCFI0:
movq %rsp, %rbp ; 创建新栈帧
.LCFI1:
movl %edi, -20(%rbp) ; 在寄存器中的参数压栈
movl %esi, -24(%rbp)
movl %edx, -28(%rbp)
movl %ecx, -32(%rbp)
movl %r8d, -36(%rbp)
movl %r9d, -40(%rbp)
movl -24(%rbp), %eax
addl -20(%rbp), %eax
addl -28(%rbp), %eax
addl -32(%rbp), %eax
addl -36(%rbp), %eax
addl -40(%rbp), %eax
addl 16(%rbp), %eax
addl 24(%rbp), %eax
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
leave
ret
movl %eax, -8(%rbp) ; 保存 add 函数返回值到栈中,对应 C 语句 int sum = add(...)
movl -12(%rbp), %eax ; 恢复寄存器 %eax 的值,与调用add前保存 %eax 相对应
movl %eax, -4(%rbp) ; 对应 C 语句 m = k,%eax 中的值就是 k。
movl $0, %eax ; main 函数返回值
leave ; main 函数返回
ret
看雪ID:有毒
https://bbs.pediy.com/user-779730.htm
推荐文章++++
* 实战栈溢出漏洞