实验 11 编写子程序
编写一个子程序,将包含任意字符,以 0 结尾的字符串中的小写字母转变成大写字母,描述如下:
1. 名称:letterc
2. 功能:将以 0 结尾的字符串中的小写字母转变成大写字母
3. 参数:ds:si 指向字符串首地址
注意需要进行转化的是字符串中的小写字母 a~z,而不是其他字符。
完整程序代码如下(Ubuntu 18.04 中的 DOSBox-X 无法运行,Windows 则 DOSBox 和 DOSBox-X 都可以运行):
assume cs:codesg
datasg segment
db "Beginner's All-purpose Symbolic Instruction Code.",0
datasg ends
codesg segment
begin: mov ax,datasg
mov ds,ax
mov si,0
call letterc
mov ax,4c00h
int 21h
letterc: cmp byte ptr [si],0
je show
cmp byte ptr [si],'a'
jb over
cmp byte ptr [si],'z'
ja over
sub byte ptr [si],20h ; 大、小写字母之间相关 20H
over: inc si
jmp letterc
; 从 show 标号开始到 call show_str(调用 show_str 子程序)都是对 show_str 子程序参数的初始化指令
show: mov ax,0B800h ; 将显示缓冲区第 0 页的段地址存入 ES 段寄存器中
mov es,ax
mov dh,8 ; 行:第 8 行
mov dl,3 ; 列:第 3 列
mov cl,2 ; 属性:绿色字体
; 计算列偏移,结果存入 DI 寄存器中
dec dl
mov ax,2
mul dl
mov di,ax
; 计算行偏移,结果加到 DI 寄存器中
dec dh
mov ax,160
mul dh
add di,ax
; 将属性编码存入 AH 寄存器
mov ah,cl
; 重置字符串起始位置
mov si,0
; 将 0 存入 CX 寄存器,以便调用 show_str 子程序时,将字符串字符码赋给 CL 寄存器时,可以通过 jcxz 指令判断是否到达字符串的末尾
mov cx,0
call show_str
ret ; 返回 letterc 子程序的主调程序 begin
; show_str 子程序从开始到结束都在一个循环之中,可以将它看作是个递归调用程序,功能相当于 C 语言中的递归函数
; 由于 (cx) 被初始化为数值 0,因此将 ds:si 字节单元传送给 CL 寄存器后,使用 jcxz 指令来判断:
; 如果 (cx)=0,说明已经到达字符串的末尾结束符 '\0',则跳至 ok 标号处返回主调程序
; 如果 (cx)≠0,说明未到达字符串的末尾结束符 '\0',则向显示缓冲区输出字符,继续执行 show_str 子程序
show_str: mov cl,[si]
jcxz ok
mov al,cl
mov es:[di],ax
inc si
add di,2
jmp short show_str ; 返回 show_str 子程序的开头,循环执行自己 —— 递归调用
ok: ret ; 返回 show_str 子程序的主调程序 show
codesg ends
end begin