5.call和ret指令
2018-08-02 本文已影响17人
芝麻酱的简书


call和ret指令使用:
assume cs:code, ds:data, ss:stack
; 栈段
stack segment
db 100 dup(0)
stack ends
; 数据段
data segment
db 100 dup(0)
string db 'Hello!$'
data ends
; 代码段
code segment
start:
; 手动设置ds、ss的值
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
; 业务逻辑
call print
mov ax, 1122h
mov bx, 3344h
add ax, bx
; 退出
mov ax, 4c00h
int 21h
; 打印字符串
print:
; ds:dx告知字符串地址
mov dx, offset string
mov ah, 9h
int 21h
ret
code ends
end start
; 函数的要素
; 1.参数
; 2.返回值
; 3.局部变量
实现函数返回值:
demo1:使用ds
assume cs:code ,ds:data ss:stack
data segment
db 100 dup(0)
data ends
code segment
start:
mov ax,data
mov ds,ax
call returnFunc
mov bx,[0]
returnFunc :
mov ax,2
add ax,ax
mov [0],ax
ret
code ends
end start
demo2:使用ds中的别名
...
data segment
;定义别名result
result dw 0
data ends
...
start:
mov ax,data
mov ds,ax
call returnFunc
mov bx,result
...
returnFunc :
mov ax,2
add ax,ax
mov result,ax
ret
demo3:通用做法是返回值直接放在ax通用寄存器中
实现函数传参:
1.使用ax寄存器存储参数来实现传递
2.使用栈来存储参数来传递,也是通用做法:
- 使用bp来快速访问栈中数据
- 使用mov sp指令来快速释放栈中数据
assume cs:code, ds:data, ss:stack
; 栈段
stack segment
db 100 dup(0)
stack ends
; 数据段
data segment
db 100 dup(0)
data ends
; 代码段
code segment
start:
; 手动设置ds、ss的值
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
; 业务逻辑
push 1122h
push 3344h
call sum3
add sp, 4
push 2222h
push 2222h
call sum3
add sp, 4
; 退出
mov ax, 4c00h
int 21h
; 返回值放ax寄存器
; 传递2个参数(放入栈中)
sum3:
; 访问栈中的参数
mov bp, sp
mov ax, ss:[bp+2]
add ax, ss:[bp+4]
ret
; 返回值放ax寄存器
; 传递2个参数(分别放ds:0、ds:2)
sum2:
mov ax, [0]
add ax, [2]
ret
; 返回值放ax寄存器
; 传递2个参数(分别放cx、dx中)
sum1:
mov ax, cx
add ax, dx
ret
code ends
end start
; 栈平衡:函数调用前后的栈顶指针要一致
; 栈如果不平衡的结果:栈空间迟早会被用完
注意区分递归调用、函数内调用函数和连续调用多个函数对栈的使用的区别,
函数内调用函数会一直往栈中压数据,而多函数连续调用,只会当前函数栈中数据释放后再继续下一个函数的压栈操作。
栈平衡的方法:
1.外平栈,函数外面进行平栈,也就是上面的操作,要是常用的做法
2.内平栈,函数内进行平栈,函数内调用其他函数的时候:
sum2:
mov ax, [0]
add ax, [2]
call sum1
ret
sum1:
mov ax, cx
add ax, dx
ret 4