【目的】
- 掌握使用JMP 和JCC 指令
- 程序设计掌握分支结构和循环结构
- 掌握单分支和双分支结构的分支语句
编程要求
- 用记事本写.ASM源程序。
- 汇编和连接源程序,生成.EXE文件(如果操作错误,请使用debug查)
- 使用Visio绘制实验流程图
编程内容
【一】分支程序编程
1.流程图:
2.源代码:
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,则跳转到NEXT相反,继续执行 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,则跳转到NEXT两段,反之亦然 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)源代码:
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即cASCII 码放到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工程文件 分支程序实验和循环程序