; 函数的调用流程
; 1.push参数
; 2.将函数的返回地址入栈(下一条指令的地址)
; 3.保护bp,将sp赋值给bp
; 4.分配一定的空间给局部变量使用(让sp减去空间大小),为了安全并使用CC填充(int 3h)
; 5.保护可能被业务代码修改的一些寄存器
; 6.具体的业务代码
; 7.恢复寄存器的值(跟第5步相反)
; 8.将bp赋值给sp,恢复bp
; 9.返回(ret)
所有代码
assume cs:code, ds:data, ss:stack
; 栈段(存放数据,比如高级语言中的局部变量)
stack segment
db 200 dup(0)
stack ends
; 数据段(存放数据,比如高级语言中的全局变量)
data segment
db 20 dup(0)
string db 'Hello World!$'
data ends
; 代码段
code segment
start:
; 设置ds、ss的值
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov cx, 8h
; 业务逻辑
push 3h
push 4h
call sum
mov dx, cx
; 退出程序
mov ah, 4ch
int 21h
; 参数:传递3个字型参数,参数放到栈中
; 返回值:返回值存放到ax中
sum:
; 保护bp
push bp
mov bp, sp
sub sp, 20 ; 20字节留作局部变量的空间
; 保护寄存器
push bx
push cx
push dx
; 用int 3填充局部变量空间
;lea di, [bp - 20]
;mov cx, 10
;mov ax, 0cccch
;mov bx, ss
;mov es, bx
;rep stosw
;******** 业务逻辑代码 begin ********
; 取出参数
; 定义一个局部变量的值是1
mov ss:[bp - 2], 1h
; 定义一个局部变量的值是2
mov ss:[bp - 4], 2h
; 修改了寄存器
mov bx, 2h
mov cx, 3h
mov dx, 4h
; 将外面传递进来的2个参数和2个局部变量相加,存储到ax中作为返回值
mov ax, ss:[bp+2]
add ax, ss:[bp+4]
add ax, ss:[bp - 2]
add ax, ss:[bp - 4]
;******** 业务逻辑代码 end ********
; 恢复寄存器
pop dx
pop cx
pop bx
; 恢复sp
mov sp, bp
; 恢复bp
pop bp
ret 4
code ends
end start
最终调用完毕函数,依旧实现了站平衡,不要执行完毕一个函数之后,突然少了一截内存,那就废了
网友评论