为了避免主函数中使用的寄存器和在子函数中使用的寄存器相互干扰,就有了一种方法去解决这个问题
这种方法是用栈来实现的
主函数中,用到了很多的寄存器,但是寄存器的数量有限,而且功能很有限制,在调用子函数之前应该把这个子函数中需要用到的寄存器先进行入栈操作,那么就相当于把主函数中用到的寄存器保存在栈中了,等子函数操作结束后,再进行出栈操作,这样一来一回就不会相互干扰了
所以有了通式:
子程序开始:子程序中使用的寄存器入栈
子程序内容
子程序中使用的寄存器出栈
返回主函数
capital: push cx
......
pop cx
ret
下面举个例子,这里的要求是计算将四组字符串都改成大写的
这里会遇到的问题就是cx在主函数和子函数中都需要背调用,于是就有了冲突,就用上面的方式解决就可以了
assume cs:code, ds:data, ss:stack
data segment
db 'word', 0
db 'unix', 0
db 'wind', 0
db 'good', 0
data ends
stack segment ;用来储存寄存器的栈,由于使用较多的都是16位的寄存器,所以开辟的是8个字空间的栈,而且栈是操作的16位数据
dw 8 dup(0)
stack ends
code segment
start: mov ax, data ;将数据段初始化
mov ds, ax
mov ax, stack ;将代码段初始化
mov ss, ax
mov sp, 16 ;栈的指针指向栈顶
mov bx, 0
mov cx, 4 ;循环四次让四个字符串都转为大写的
s0: call m ;调用子函数
inc bx ;这句很重要",不加会使程序因为cx=0跳出到ok处
loop s0
mov ax, 4C00H
int 21H
;该子函数的作用是将一个字符串转换为大写
m: push cx ;子函数的开始,先将子函数中用到的cx入栈
s: mov cl, ds:[bx]
mov ch, 0
jcxz ok ;如果cx==0,那么jcxz就会跳到ok处执行
jmp s1
s1: and byte ptr ds:[bx], 11011111B
inc bx
jmp s
ok: pop cx ;子函数结束,将之前入栈的cx拿出来
ret ;返回主函数
code ends
end start