书本所用的方法是,使用两个并列的 loop 循环,分别实现两个字符串大、小写字母的转换。其中以下 3 条指令存在重复使用:
mov al,[bx]
mov [bx],al
inc bx
为避免重复使用相同代码,以达到减少代码量目的,设计以下算法:
assume cs:codesg,ds:datasg
datasg segment
db 'BaSiC'
db 'iNfOrMaTiOn'
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax ; 设置 ds 指向 datasg 段
mov bx,0 ; 设置 (bx)=0,ds:bx 指向“BaSiC”的第一个字母
mov dx,8 ; (dx)=两个字符串的长度差+2
s: mov al,[bx] ; 将 ASCII 码从 ds:bx 所指向的单元中读取到 AL 寄存器
and al,11011111B ; 将 AL 寄存器中存储的 ASCII 码第 5 位二进制数值置为 0,变为大写字母
mov [bx],al ; 将转变后的 ASCII 码写回原内存单元
u: add bx,5 ; 将“BaSic”的长度加到 bx 上,使得 ds:[bx] 指向“iNfOrMaTiOn”相应的字符
mov ah,[bx] ; 将 ASCII 码从 ds:bx 所指向的单元中读取到 AH 寄存器
or ah,00100000B ; 将 AH 寄存器中存储的 ASCII 码第 5 位二进制数值置为 1,变为小写字母
mov [bx],ah ; 将转变后的 ASCII 码写回原内存单元
sub bx,5 ; 恢复 bx 的值
; 设置 cx 与 bx 的距离,并将该距离值存入 CX 寄存器:
; 1. 当较短的字符串未转换完成之前,该距离等于较短字符串的长度;
; 2. 当较知的字符串已转换完成,该距离总是等于 1,
mov ax,11 ; 将较长的字符串的长度值存入 AX 寄存器
sub ax,dx
add ax,2
mov cx,ax
sub cx,bx
inc bx ; (bx) 加 1,ds:bx 指向下一个字母
loop s ; “BaSiC”转换完成后,loop s 指令执行结果为 (cx)=0,以终止 s 标号循环
; 设置 loop u 循环计数器,令当 (dx)=0 时,终止 loop u 循环,即 (cx)=0
sub dx,1
mov cx,dx
loop u
mov ax,4c00h
int 21h
codesg ends
end start