函数调用栈平衡
2021-06-07 本文已影响0人
甲乙飞鱼
栈平衡
- 栈平衡:函数调用前后的栈顶指针指向的位置不变
内平栈 外平栈
- 内平栈: 指的是在函数调用返回之前使栈保持平衡(一般使用寄存器传参一般都是内平栈)
- 外平栈:在函数调用后通过操作使栈保持平衡 (一般使用栈传参的是外平栈)
函数的调用流程 (使用栈传参)
- push参数
- push函数的返回地址
- push bp (保留bp之前的值,方便以后恢复bp的值)
- mov bp, sp (保留sp之前的值,方便以后恢复sp)
- sub sp, 空间大小 (分配空间给函数内部的局部变量使用)
- 保护可能用到的寄存器
- 填充局部变量的的空间
- 执行业务逻辑
- 恢复寄存器之前的值
- mov sp, bp (恢复sp之前的值)
- pop bp (恢复bp之前的值)
- ret (将函数的返回地址出栈,执行下一条指令)
- 恢复站平衡 (add sp, 参数占用的空间)
- sp 寄存器:栈顶的内存地址
- bp 寄存器:辅助sp寄存器的寄存器
- sp 指向栈顶
- 方法结束后又要指向栈里面的函数返回地址
- 需要一个记录员 当sp不指向栈里面的函数返回地址 时记录下sp当前的位置
- 所以当参数入栈之后 函数返回值地址入栈后先要 保护bp寄存器的值
; 返回值放ax寄存器
; 传递2个参数(放入栈中)
sum:
; 保护bp
push bp
; 保存sp之前的值:指向bp以前的值
mov bp, sp
; 预留10个字节的空间给局部变量
sub sp, 10
; 保护可能会用到的寄存器
push si
push di
push bx
; 给局部变量空间填充int 3(CCCC)
; stosw的作用:将ax的值拷贝到es:di中,同时di的值会+2
mov ax, 0cccch
; 让es等于ss
mov bx, ss
mov es, bx
; 让di等于bp-10(局部变量地址最小的区域)
mov di, bp
sub di, 10
; cx决定了stosw的执行次数
mov cx, 5
rep stosw
; rep的作用:重复执行某个指令(执行次数由cx决定)
; -------- 业务逻辑 - begin
; 定义2个局部变量
mov word ptr ss:[bp-2], 3
mov word ptr ss:[bp-4], 4
mov ax, ss:[bp-2]
add ax, ss:[bp-4]
mov ss:[bp-6], ax
; 访问栈中的参数
mov ax, ss:[bp+4]
add ax, ss:[bp+6]
add ax, ss:[bp-6]
; -------- 业务逻辑 - end
; 恢复寄存器的值
pop bx
pop di
pop si
; 恢复sp
mov sp, bp
; 恢复bp
pop bp
ret
函数调用流程图.png