1. 预备知识
- 基于位运算实现大小写字母的转换。将字符转换为大写字符:and 1101 1111,将字符转换为小写字符:or 0010 0000,见实验 6。
- 转移指令 cmp 通过影响标志位来实现转移,见检测点 11:
指令 | 含义 | 检测的相关标志位 |
---|---|---|
je | 等于则转移 | ZF=1 |
jne | 不等于则转移 | ZF=0 |
jb | 小于则转移 | CF=1 |
jnb | 不小于则转移 | CF=0 |
ja | 大于则转移 | CF=0 且 ZF=0 |
jna | 不大于则转移 | CF=1 或 ZF=1 |
2. 实验任务
编写一个子程序,将包含任意字符,以 0 结尾的字符串中的小写字母转变成大写字母。描述如下:
名称:letterc
功能:将以 0 结尾的字符串中的小写字母转变成大写字母
参数:ds:si 指向字符串首地址
应用举例:
assume cs:codesg
datasg segment
db "Beginner's All-purpose Symbolic Instruction Code.",0
datasg ends
begin:
mov ax,datasg
mov ds,ax
mov si,0
call letterc
mov ax,4c00h
int 21h
letterc:
;待完成部分
codesg ends
end begin
注:需要进行转化的是字符串中的小写字母 a~z,而不是其他字符。
- 实验 6 中有相似的需求,根据位运算作用域每个字符,将大 / 小写字母转换为小 / 大写字母。而本题要求转化操作仅作用于小写字母,所以需要判断当前读取的字符是否为小写字母。
- 预备知识提到,cmp 比较指令有条件判断的功能。而小写字母 a~z 的 ASCII 码范围为 97~122。
- 根据实验 10,使用 jcxz 转移指令配合寄存器 CX 判断当前读取的字符是否为 0。得到整体代码为:
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 ;段寄存器DS指向datasg段
mov si,0
call letterc ;子程序调用
mov ax,4c00h
int 21h
letterc:
push cx ;将子程序用到的寄存器内容入栈
push si
mov cl,ds:[si] ;取字符串中的字符
jcxz exit ;如果CX等于0则退出
cmp cl,97
jb help ;如果ASCII值小于97则转移至help
cmp cl,122
ja help ;如果ASCII值大于122则转移至help
and cl,11011111b ;通过逻辑与运算将字母转换为大写字母
mov ds:[si],cl ;将转换后的字符重写回对应的内存单元
jmp short help ;转移实现类似循环的功能
help:
inc si ;偏移1个字节取字符
jmp short letterc ;循环
exit:
pop si
pop cx ;将子程序用到的寄存器内容入栈
ret ;子程序返回
codesg ends
end begin
其中:help 部分用于偏移字节和结合转移指令实现类似循环功能。转换前数据所在单元的情况:
转换后数据所在单元的情况:
由结果可知,该转换仅针对小写字母,不影响 '
、-
、.
等其他字符。
3. 总结
该程序主要借助比较指令和转移指令来实现条件判断。