DOS汇编分支、循环编程与寄存器分析

2022-07-20 14:32:06 浏览数 (1)

【目的】

  1. 掌握使用JMP 和JCC 指令
  2. 掌握分支结构、循环结构的程序设计
  3. 掌握单分支和双分支结构的分支语句

【编程要求】

  1. 用记事本编写.ASM源程序。
  2. 对源程序进行汇编及连接,产生.EXE文件(如果运行错误就用debug查)
  3. 使用Visio绘制实验流程图

【编程内容】

【一】分支程序编程

编写一个程序,把AL寄存器中的两位十六进制数显示出来。

1.流程图:
2.源代码:
代码语言:javascript复制
CODE SEGMENT  ;定义代码段
ASSUME CS:CODE ;将代码段与CS寄存器链接起来
START: 
MOV AL,3EH ;开始代码段,将3EH存入AL寄存器中
MOV BL,AL ;将AL中的值存入BL中
MOV DL,AL ;将AL中的值存入DL中
MOV CL,4 ;将4存入CL中
SHR DL,CL ;将DL右移CL位(4位)
CMP DL,9 ;将DL中的内容和9作比较,即进行DL-9的运算
JBE NEXT1 ;若DL中的内容小于等于9,则跳转到NEXT1,反之,继续执行
ADD DL,7 ;把DL中的数据加7
NEXT1:ADD DL,30H ;NEXT1部分:将DL中的数据加30H
MOV AH,2 ;将2存入AH中
INT 21H ;中断,此时AH中的内容为2,因此输出字符
MOV DL,BL ;将BL中的内容转移到DL中
AND DL,0FH ;将DL和0F按位进行逻辑与运算
CMP DL,9 ;将DL中的内容和9作比较,即进行DL-9的运算
JBE NEXT2 ;若DL中数据小于等于9,则跳转到NEXT2段,反之继续进行
ADD DL,7 ;将DL中的内容加7
NEXT2:ADD DL,30H ;NEXT2 段:将DL的数据加上30H
MOV AH,2 ;将2存入AH中
INT 21H ;中断,此时AH中的内容为2,因此输出字符
MOV AH,4CH ;将AH 中的内容设置为4CH
INT 21H ;中断,此时AH中的内容为4C,因此返回DOS 系统
CODE ENDS ;结束代码段
END START ;结束该程序
3.实验代码、过程、相应结果的说明和分析:

(1)用记事本编写DISPHEX.ASM 程序,并将文件保存在目标目录下。

(2)在DOS环境下对asm文件进行编译,生成.obj文件

(3)链接生成可执行文件.exe

​ 用dir命令查看当前目录的全部文件。

(4)运行exe文件,显示最终结果为3E。

(5)为了进一步熟悉程序的逻辑过程,我又使用debug对程序进行了分析。

整个代码的逻辑是先逐位比较,先比较高位数据,比较完后直接输出高位,再比较低位的,比较完后输出低位。其中比较的规则为:因为是十六进制的数,有十个数字和六个字母组成。首先进行数字的比较,小于等于9 的直接输出数字。但对于大于9 的数字,由于ASCII码最小的字母A 和数字9 的ASCII 码相差了7,因此需要加7进行转换,再进行显示。

(6)此时用SHR 操作使DL 的值向右移动了4 位。DL 从00111110到00000011 再与09 进行比较,小于等于09 所以发生了JBE 跳转,此时可以看到IP也发生了跳转 。

(7)输出高位数字:由于0 的ASCII 码是30H,所以加上30H 使其成为ASCII码。在此之后,用MOV AH,02 和INT 21H 产生中断,并输出DL 的值。

(8)比较低位:将之前放在BL 的值重新放回DL 中,然后将DL 的值和0F进行位与操作。然后与9 作比较,在加7 再加上30 将其转变为ASCII 码。

(9)输出低位数字:用MOV AH,02 和INT 21H 的操作产生中断,并输出低位数字。

(10)显示数字,然后用MOV AH,AC 和INT 21H 操作结束程序,返回DOS。

【二】循环程序编程
(1)流程图:
(2)源代码:
代码语言:javascript复制
CODE SEGMENT ;定义代码段
ASSUME CS:CODE ;将代码段与CS寄存器链接起来
START: ;代码段开始
MOV AH ,1  ;将1存入AH中
INT 21H  ;因为AH=1,产生中断
MOV BL,AL  ;将AL的内容存入BL 中
CMP BL,0DH  ;将BL的内容与0D进行比较(回车的ASCII码是0D)
JE JUDGE  ;进行判断,若相等,则执行JUDGE操作。不相等则继续下一步
CMP BL,'1'  ;比较BL的数值与‘1’的ASCII 码的大小
JB START  ;若小于,则返回start 操作。大于等于则继续下一步
CMP BL,'9'  ;比较BL的数值与‘9’的ASCII 码的大小
JBE NEXT1  ;进行判断,若小于等于,进行NEXT1操作。若大于则继续下一步
CMP BL,'A'  ;比较BL的数值与‘A’的ASCII 码的大小
JB START  ;相等的情况下,返回START 操作。不相等则继续下一步操作
CMP BL,'Z'  ;比较BL的数值与‘Z’的ASCII 码的大小
JBE NEXT2  ;进行判断,若小于等于,进行NEXT1操作。大于则继续下一步
CMP BL,'a'  ;比较BL的数值与‘a’的ASCII 码的大小
JB START  ;进行判断,相等的情况下,返回START操作。不相等则继续下一步
CMP BL,'z'  ;比较BL的数值与‘z’的ASCII 码的大小
JBE NEXT2  ;进行判断,若小于等于,进行NEXT1操作。大于则继续下一步
NEXT1:MOV DL,BL  ;将BL的值存入DL中
MOV AH,2  ;将2的值存入AH,产生中断
INT 21H  ;输出该数字
JMP START  ;返回START 操作
NEXT2:MOV DL,'c'  ;把’c’的ASCII 码的值放到DL中
MOV AH ,2  ;将2的值存入AH,产生中断
INT 21H  ;输出这个数字
JMP START  ;返回START操作
JUDGE:MOV AH,4CH  ;让AH 的值等于4C
INT 21H  ;中断,因为AH为4C,返回DOS系统
CODE ENDS  ;代码段结束
END START  ;程序结束
(3)实验代码、过程、相应结果的说明和分析:

(1)用记事本编写DISPHEX.ASM 程序

(2)在DOS环境下对asm文件进行编译,生成.obj文件

(3)链接生成可执行文件.exe

用dir命令查看当前目录的全部文件。

(4)运行exe文件,输入测试样例15assembly,查看最终显示结果如下,符合题目要求,因此程序设计成功。

(5)同样,我也使用debug对程序进行了进一步的验证。

(6)此次选择的测试样例为字母a。由程序可知,通过MOV AH,01 和INT 21 指令输入所要归类的字符,然后输入字母a,AX 的低位变成a 的ASCII 码61。然后将AL 放入BL 中,并将其与0D进行比较,得到的结果为NZ,说明a和回车不相等,而此时JZ 为相等则跳转,因此继续执行。此后将BL 与31 即1 的ASCII 码进行比较,看是否为小于1 的ASCII 码。

(7)得到的结果为PL,说明a 的ASCII 码比1 大,继续下一步;然后与39进行比较,得到的结果为PL,说明a 的ASCII 码比9 大,说明a 不在数字的范围,JBE 为小于等于跳转,因此不跳转,继续下一步,接着将BL 与41 即大写字母A 的ASCII 码进行比较,比较判断的是否9 和A 之间的字符。

(8)得到的结果为PL,说明不是在1 和A 之间的字符,而JB 为小于则跳转,于是此时不执 行跳转,程序继续。再与Z 的ASCII 码(5A)进行比较,发现结果为PL,说明也不在大写字母的范围之中,于是继续与61 即a 的ASCII 码进行比较,看是否为Z-a的其他字符。发现比较结果为PL,说明不是其他字符,则继续下一步,将其与z 的ASCII 码(7A)进行比较,得到的结果为NG,说明是小写字母的范围,接着跳转到地址0031,此时将63也就是c的ASCII 码放到DL 中,准备实现输出。

(9)将AL 存在DL 之中,接着通过MOV AH,02 和INTT 21 指令将DL 中的内容输出,即把ASCII 码转换为字符输出。由结果可知,程序设计成功。

【总结心得】

我第一次以一个程序设计者的角度使用汇编语言,因此在实验中遇到了不少的困难,但无论从实践还是知识原理的角度给我带来了很大的改变。

首先在程序设计的过程中,我体会到了流程图的好处,也是真正理解了老师为什么强调用流程图表示,在已知实现的目标,设计程序时,首先要进行的就是整体逻辑的分析,而在分析其中逻辑的时候,流程图清晰明了,对于整个程序的框架设计很有帮助,同时我也学会了使用Visio软件。

其次,我也对汇编书上的知识有了实验角度的认知与理解。例如,对于int指令,在书上第一次看到这个指令的介绍时,我总是很困惑,为什么是21H?不是别的数字呢?这个疑惑在进一步学习并且实验实践中得到了解答,21H是中断向量号,是dos操作系统提供的各种功能服务程序。程序通过调用INT 21H来和系统接口。类似于于windows下调用API。INT 通过AH 不同的值来实施不同的操作。在实验中通过尝试01,02,4CH等指令分别实现了用键盘输入后返回AH、调用DL 输出、返回DOS 环境等操作。此外,我还复习了SHL与SHR的知识,更好的理解了老师给出的样例程序。在做设计实验的过程中,我有时还是会犯一些错误,比如把ASCII码的十进制写入代码进行判断,结果输出与预想的不一致,通过debug后才想起来要使用十六进制的ASCII码值,因此我也再次查阅了ASCII码表,并且记住其中标志性的ASCII码值,例如A的ASCII码为41H,a的为61H,数字‘1’的为31H。这在设计程序时对我的帮助很大。

初学汇编,可能存在错误之处,还请各位不吝赐教。

受于文本原因,本文相关实验工程无法展示出来,现已将资源上传,可自行下载。

山东大学微处理器原理实验2.2工程文件 分支程序实验和循环程序

0 人点赞