MOV AH,9 INT 21H
MOV CX,5;输入五个数字 MOV SI,0
INPUT: LEA DX,[SHU1+SI];输入要排序的原始数据 MOV AH,10 INT 21H
MOV DL,10;输入后换行 MOV AH,2 INT 21H
ADD SI,5;指针加5,指向下一个变量 LOOP INPUT CLD
MOV CX,4;设定排序外循环次数 A: MOV BP,0
PUSH CX;外循环次数入栈 PX: PUSH CX MOV CX,3
LEA SI,[SHU1+BP+2];逐位比较两个数大小 LEA DI,[SHU1+BP+7] REPZ CMPSB
JB B;如果小于直接比较下一个数,否则两个数对换位置 MOV CX,3
Jh: MOV AL,SHU1[BP+2] XCHG AL,SHU1[BP+7];将两个字节对换位置,循环3次即完成这两个数的交换
XCHG AL,SHU1[BP+2] INC BP LOOP Jh SUB BP,3
B: ADD BP,5;指向后面两个数字 POP CX LOOP PX
POP CX;外循环次数出栈 LOOP A
LEA DX,SHUCHU;输出字符串'PAI XU HOU DE SHU JU SHUN XU SHI:' MOV AH,9 INT 21H MOV CX,5 MOV SI,2
OUTPUT:PUSH CX;计数器入栈实现循环嵌套 MOV CX,3
L: MOV AL,[SHU1+SI];输出排序后的5个数字 MOV DL,AL
MOV AH,2 INT 21H INC SI LOOP L MOV DL,2CH MOV AH,2 INT 21H ADD SI,2
POP CX;计数器出栈 LOOP OUTPUT MOV DL,10 MOV AH,2 INT 21H MOV DL,0DH MOV AH,2 INT 21H
LEA DX,MAX;输出字符串'ZUI DA ZHI SHI:' MOV AH,9
INT 21H MOV CX,3 MOV SI,2
D: MOV DL,[SHU5+SI];输出最大值 MOV AH,2 INT 21H INC SI LOOP D
MOV DL,10;换行 MOV AH,2 INT 21H
MOV DL,0DH MOV AH,2 INT 21H
LEA DX,MIN;输出字符串'ZUI XIAO ZHI SHI:' MOV AH,9
INT 21H MOV CX,3 MOV SI,2
E: MOV DL,[SHU1+SI];输出最小值 MOV AH,2 INT 21H INC SI LOOP E MOV DL,10 MOV AH,2
INT 21H MOV DL,0DH MOV AH,2 INT 21H
LEA DX,AVERAGE;输出字符串'PING JUN ZHI SHI:' MOV AH,9 INT 21H MOV CX,3
MOV BX,10;除数10 MOV SI,2 AD: MOV DX,0 MOV AH,0 PUSH CX MOV CX,3 ZH: MOV AL,[SHU2+SI];将十进制数转换为二进制数,为后面求平均值做准备 SUB AL,30H PUSH AX MOV AX,DX MUL BX MOV DX,AX POP AX ADD DX,AX INC SI
LOOP ZH;执行3次完成3个十进制数的转换 ADD SI,2 POP CX
ADD HE,DX;将DX的数放在HE中
LOOP AD;循环后得到三个十进制数转换为二进制数之后的相加和 MOV DX,HE; MOV AX,DX XOR DX,DX MOV BX,3
DIV BX;除3取平均值,结果将商放在AX中,余数放在DX中
MOV BX,AX;给BX赋值平均数,然后将BX中表示的十进制数转换为对应的字符串
DIV CHUSHU;除100取最高位 ADD AL,30H;转换为ASCII码 MOV AVER,AL MOV AL,AH XOR AH,AH
DIV [CHUSHU+1];除10取十位 ADD AL,30H
ADD AH,30H;余数就是个位 MOV [AVER+1],AL
MOV [AVER+2],AH MOV CX,3
MOV SI,0
F: MOV DL,[AVER+SI];输出平均值 MOV AH,2 INT 21H INC SI LOOP F MOV DL,10 MOV AH,2 INT 21H MOV DL,0DH MOV AH,2 INT 21H
LEA DX,STR2 ;输出字符串'PING JUN ZHI DE ER JIN ZHI CHUAN SHU CHU:’ MOV AH,9 INT 21H
MOV CX,16 MOV SI,0
G: RCL BX,1;将平均数转换为二进制串 JNC H
ADD [STR1+SI],1;如果不为0就将其加1变成1的ASCII码值 H: MOV DL,[STR1+SI];将二进制串逐个输出 MOV AH,2 INT 21H INC SI
LOOP G MOV AH,4CH INT 21H CODES ENDS
END START 运行结果:
四.实验感想和收获
本次实验相较于第一次难度增大了很多,本人花了大约12个小时才做完。 第一个练习很简单,从编译到连接都是一次通过,在用DEBUG调试发现结果却实正确。不过在做第二个练习时我遇到了困难,完全没有思路。当时不知道怎么对一位一位的数据进行操作,在看书的过程中无意中发现了循环指令,我才意识到用SHL指令可以实现这个功能。第三个联系主要考查我们对中断指令的了解程度,我实现地是一位数的加法,不过后来老师发给了我们他自己编的版本,我感慨道编程真是一门大学问,要考虑到各种各样的功能,人机互动,可能出错的地方。这都是需要大量的实践积累才行。
在编写冒泡排序法这个程序时我遇到了很多困难。起初在编写一段循环指令时,未把寄存器CX入宅,所以影响了其他部分的循环次数,导致结果出错。所以今后编程时一定要把有用的信息入宅,防止被其他指令所改变。在输出字符时,必须记得把要输出字符的值转变成ASCI码,我期初输出数字时就忘记了这一步导致出了很多差错。同时在将二进制数转变成BCD吗输出时可以通过除10来实现,将得到的商继续除10,而得到的余数就是个位的值,同理,再次除10得到的余数就是10位。所以通过适当此处的出发可以将二进制数转变为BCD码。
通过亲身实践这次试验,对汇编语言编程有了初步的认识,也体会到了编程的整个过程。从读题,设计程序框架到写代码,步步承接,同时将课堂上所学的知识运用起来,在加深理解的同时也发现了自己很多不懂的地方,于是通过自己查资料,问老师终于将程序一步步地调试正确得出期望的结果,那种自豪和满足感油然而生。
第三次实验 8253定时器/计数器与接口实验
一.功能说明
计算机是如何产生音乐和声响的呢?原来在计算机中有一个可编程时间间隔定时器8253,它能根据程序提供的计数值和工作模式,产生各种形状和各种频率的计数/定时脉冲,提供给系统的各个部件使用。它还可以产生不同频率的脉冲作为扬声器的声源。
在8253定时器内部有3个独立工作的计数器:Counter0, Counter1, Countre2,每个计数器都分配有一个端口地址,分别是40H,41H,42H。8253内部还有一个公用的控制寄存器,端口地址为43H,端口地址输入到8253的CS,A1,A0端,分别对三个计数器和控制器寻址。
对8253编程时,先要设定控制字,以选择计数器,确定工作模式和计数值的格式,每个计数器由三个引脚与外部联系,CLK为时钟输入端,GATA为门控制信号输入端,OUT为计数/定时信号输入端。每个计数器是以倒计数的方式计数,也就是说,从计数初值开始逐次减1,直到减为0为止。
端口地址与计数器的关系: 40H 选中计数器0:作为定时器为系统日时钟提供计时基准 41H 选中计数器1:作为定时器使用 ——乐曲程序