实验一、认识Tddebug集成操作软件
一.实验内容
(一) 实验题目:数据传送实验
1. 编程将数据段中的一个字符串传送到附加段中,并输出附加段中的目标字符串到屏幕上。
2. 修改此程序,采用字符串传送指令完成。
(二) 实验目的:通过对该程序进行调试,查看程序段、数据段、附加段装入内存后的分
配情况。单步执行数据传送指令后,观察各个寄存器及数据区的内容。
(三) 实验步骤:
1. 运行Tddebug软件,选择Edit菜单编写实验程序
2. 使用Compile菜单中的Compile和Link对实验程序进行汇编、连接,生成执行文
件。
3. 使用Rmrun菜单中的Run运行程序,观察运行结果。
4. 使用Rmrun菜单中的Debug调试程序,查看程序段、数据段、附加段装入内存后
的分配情况。单步执行数据传送指令后,观察各寄存器及数据区的内容。过程如下:
1) 按F7单步执行,在代码区中有一个三角,表示正在执行的指令。每一条指令
的执行一定会使目标寄存器和状态寄存器发生变化,从相关窗口看结果。
2) 检查内存数据区的内容,关键是找出用户程序的数据段和附加段:
? 方法1:在CPU窗口按Tab键使内存数据显示区成为活动区,按Ctrl+G键,? 输入:“DS或ES寄存器的值:偏移地址”,即可显示用户指定的数据区 方法2:选择菜单View| Dump,弹出内存数据显示窗口。
3) 查看执行结果:按Alt+F5,切换到用户窗口。
5. 更改数据区中的数据,考察、调试程序的正确性。
二.分析设计思想,绘制实验原理图、流程图。
汇编语言程序的开发过程如图1.1所示,这个过程主要有编辑、编译、链接几个步骤构成。
三.程序清单及相关注释。
DDATA SEGMENT
MSR DB “HELLO,WORLD!$”
LEN EQU $- MSR
DDATA ENDS
EXDA SEGMENT
MSD DB LEN DUP(?)
;定义源数据段 ;定义附加数据段 1
EXDA ENDS
;定义堆栈段 MYSTACK SEGMENT
STACK DW 20 DUP(?)
MYSTACK ENDS
CODE SEGMENT ;定义代码段
ASSUME CS:CODE,DS:DDATA,ES:EXDA
START: MOV AX,DDATA
MOV DS,AX MOV AX,EXDA MOV MOV MOV MOV MOV ES,AX SI,OFFSET MSR DI,OFFSET MSD CX,LEN BX,0 ;装载数据段寄存器 ;装载附加数据段寄存器
NEXT: MOV AL,MSR[BX] ;开始传输数据
MOV ES:MSD[BX],AL
INC LOOP PUSH BX NEXT ES
;将附加段寄存器指向的段值赋给数据段寄存器 POP DS
MOV DX,OFFSET MSD
MOV AH,9 INT 21H MOV AH,4CH INT 21H ;显示字符串 ;返回DOS状态
CODE ENDS
END START
四.实验结果并分析。
五.收获体会及实验中遇到的问题和解决方法。
在这次试验中主要是掌握tddebug的开发环境,了解汇编语言的基本程序。由于刚 2
刚接触汇编语言和开发环境,各项知识都显的比较薄弱,遇到了很多操作上的基本问题。比如使用快捷键进行界面操作不太熟练等。由于代码段相对比较长,很多地方还需在老师的指导下才能看懂,直接将代码程序打出来会出现很多由于不理解粗心等造成的失误使之不能编译成功。后来尝试将程序代码复制并另存为ASM格式之后就可以直接编译方便了很多灵活了很多。今后还需在理论课堂上多下功夫,进一步对汇编深入学习。
实验二、I/O程序设计
一.实验内容:I/O程序设计
(一)实验内容:
1.编程由键盘输入任意一个字符,将该字符的ASCII码值显示在屏幕上。
2.从键盘输入两个1位十进制数,计算二者之和,并将结果显示在屏幕上。
3.编程由键盘输入任意一位数,将该数以二进制数形式显示在屏幕上,例:
5=00000101B
(二) 实验步骤:
1. 画出实验流程图。
2. 运行Tddebug软件,选择Edit菜单编写实验程序
3. 使用Compile菜单中的Compile和Link对实验程序进行汇编、连接,生成执行文
件。
4. 使用Rmrun菜单中的Run运行程序,观察运行结果。
5. 使用Rmrun菜单中的Debug调试程序。单步执行指令,观察各寄存器及数据区的
内容。
6. 更改数据区中的数据,考察程序的正确性。
二. 分析设计思想。
设计思路:首先将该数以十六进制数形式分解,然后将每一位分别转换为ASCII码送屏幕显示。其中0H~9H之间的数加30H,即可得0H~9H的ASCII码,而AH~FH的ASCII码,则需再加7H,参见表5-1。参考程序流程如图2-1所示。示例程序参见参考程序清单。
三.
DATA 程序清单及流程 SEGMENT
MES DB ‘Show a as hex:’,0AH,0DH,’$’
SD DB ‘a’
DATA
CODE ENDS SEGMENT
MOV AX,DATA
MOV DS,AX
MOV
MOV DX,OFFSET MES ;显示提示信息 AH,09H
SI,OFFSET SD
AL,DS:[SI]
3 ASSUME CS:CODE,DS:DATA START: INT 21H MOV MOV
AND AL,0F0H ;取高4位
MOV CL,4
SHR AL,CL
CMP AL,0AH ;是否是A以上的数
JB C2
ADD AL,07H
C2: ADD AL,30H
MOV MOV INT MOV AND CMP JB 21H AL,DS:[SI] AL,0FH ;取低4位 AL,0AH C3 ;显示字符 DL,AL AH,02H
ADD AL,07H
C3: ADD AL,30H
MOV MOV INT MOV INT DL,AL AH,02H 21H AH,4CH 21H ;显示字符 ;返回DOS
CODE ENDS
END START
四. 实验结果。
五. 收获体会。
在实验中,加强了对理论知识的掌握,由于堂上的知识太多平时不能很好的理解,在具体的实践中更加巩固了我对理论知识的认识,增强了汇编语言的编程语感。汇编语言是底层的硬件语言,和C语言有类似的地方,也有不一样的地方,所以在实际编程的过程中写给代码段测试结果,加深对理论知识的灵活掌握,为今后逐步增加难度的编程序学 4
习中打好一定的基础。
实验三、循环程序设计
一. 实验内容
1.求某数据区内负数的个数
2.试编程统计数据区中正数、零和负数的个数。
3. 编程求无符号数字节序列中最大值和最小值。
4.从键盘输入一字符串,搜索该字符串中是否有字符“A”,若有请输出其在串中的位置。
二.分析设计思想
1.求某数据区内负数的个数为统计数据区内负数的个数,需逐个判别区内的每一个数据,然后将所有数据中凡是符号位为1的数据个数累加起来,即得到区内包含负数的个数。参见程序清单.
2.试编程统计数据区中正数、零和负数的个数。
3.编程求无符号数字节序列中最大值和最小值
实验中可使用BH和BL作为暂存现行最大值和最小值,且
在初始时将BH和BL初始化为首字节的内容,循环依次比较每个字节的内容,求得最大值(存于BH中)和最小值(存于BL中),送屏幕显示。
三. 程序清单及相关注解
;确定数据区NUMB中负数的个数(存放于BL中)
5
DDATA SEGMENT
NUMB DB 12H,88H,82H,89H,33H,90H,01H,10H,0BDH,01H MES DB ‘The number of negative is:$’
DDATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DDATA
START:MOV AX,DDATA
MOV
MOV
XOR DS,AX DI,OFFSET NUMB BL,BL
CX,10 MOV
A1: MOV AL,[DI]
TEST AL,80H
JE
INC
A2: INC A2 BL DI
LOOP A1 ;统计负数个数
MOV
MOV
INT
MOV DX,OFFSET MES AH,09H 21H AL,BL ;显示负数个数,注意与实验二所使 用的方法的区别
6
MOV CX,2 A3: PUSH CX
MOV CL,4 ROL AL,CL POP CX MOV BL,AL AND AL,0FH CMP AL,0AH JB A4 ADD AL,07H A4: ADD AL,30H
MOV DL,AL MOV AH,02H INT 21H MOV AL,BL LOOP A3 MOV AH,4CH INT 21H
CODE ENDS
END START
四. 实验结果并分析。
7
六.收获体会。
在本次实验中基本了解了试编程统计数据区中正数、零和负数的个数的方法,对数值的进制有进一步了解,求某数据区内负数的个数为统计数据区内负数的个数,需逐个判别区内的每一个数据,然后将所有数据中凡是符号位为1的数据个数累加起来,才能得到区内包含负数的个数。实验中可使用BH和BL作为暂存现行最大值和最小值。我对代码段中的存储器用法基本掌握,对编程的思想还需进一步加强。
实验四、代码转换程序设计
一.实验内容
1.将5位十进制数的数字串转换为一个字的二进制数
2.编写程序将内存中一个字的数转换为十进制数的数字串显示。
3.编程将十进制的数字串转换为BCD码
4.编程将BCD码转换为二进制数
5.编程将二进制数转换为十进制数显示
二.分析设计思想
8
计算机输入设备输入的信息一般是由ASCII码或BCD码表示的数据或字符,CPU一般均用二进制数进行计算或用其他信息进行处理,处理的结果又必须依照外设的要求变为ASCII码、或BCD码或七段显示码等。因此,在应用软件中,各类数制的转换和代码的转换是必不可少的。计算机与外设间的数码转换关系如图6-1所示,数码对应关系如表6-1所示。
1. 将十进制数的数字串转换为二进制数
十进制数可以表示为:
Dn?10n?Dn?1?10n?1????D0?100i?Di?10
其中Di代表十进制数1、2、3、?、9、0。
上式可以转换为:
i?D
?10?(((Dn?10?Dn?1)?10?Dn?2)?10???D1)?10?D0 i由上式可归纳出十进制数转换为二进制数的方法:从十进制数的最高位Dn开始做乘10
加次位的操作,依次类推,则可求出二进制数结果。
本实验要求将缓冲区中的一个5位十进制数00012的ASCII码转换成二进制数,并将转换结果以十六进制数形式000C按位显示在屏幕上。转换过程的参考程序清单见后参考程序清单1,参考流程如图3-2所示。
修改该示例程序,从键盘任意输入5个数,实现转换并显示。
2. 将内存中一个字的数转换为十进制数的数字串。
十六位二进制数(一个字)的值域为0~65535,最大可转换为5位十进制数。五位十进制数可表示为:
9
ND?D4?104?D3?103?D2?1021?D1?10?D0
因此,将十六位二进制数转换为5位ASCII码表示的十进制数数字串,即采用除10取余方法,分别求D0~D4,并将它们转换为ASCII码。以字符串方式显示在屏幕上。转换部分
的参考流程参见图6-4。
假设缓冲区中存放的数是000CH转换成十进制数的数字串后,在屏幕显示“00012”。
3. 将十进制数的数字串转换为BCD码
(1)本实验要求将一个5位十进制数的数字串“54321”的ASCII码存放在数据区中,转换为BCD码后,将转换结果分别显示在屏幕上,即显示:01,02,03,04,05。若输入的不是十进制数的ASCII码,则输出“FF”。提示:一个字节取其低4位即变为BCD码。转换部分的实验参考流程见图6-3。
(2)修改程序,实现从键盘输入5位十进制数54321,转换BCD码后以输入顺序一致显示,即显示:05 04 03 02 01
4. 编程将BCD码转换为二进制数
本实验要求将4个二位十进制的BCD码存放在某一段内存单元中,转换出的二进制码存入其后的存储单元中,转换结果以十六进制方式送屏幕显示。转换部分的实验流程参见图6-5。
假设4个十进制数是:17,34,51,68
用BCD码表示为:01H,07H,03H,04H,05H,01H,06H,08H
显示为:0011,0022,0033,0044
三.程序清单及相关注解
;将十进制数的数字串转换为数
DDATA SEGMENT
MES DB ‘The ascii code of decimal code are:$’
BUF DB 30H,30H,30H,31H,32H ;十进制00012的ASCII码
DB 10H DUP(0)
DDATA ENDS
CODE SEGMENT ASSUME CS:CODE,DS:DDATA MOV DS,AX MOV SI,OFFSET BUF 10 START:MOV AX,DDATA
MOV BL,0AH ;送被乘数 MOV CX,0004H ;送转换位数 MOV AH,00H
MOV AL,[SI] ;取第一位ASCII码 SUB AL,30H
A1: INC SI
IMUL BL ;乘10
ADD AL,[SI]
SUB AL,30H
LOOP A1
MOV BX,AX
MOV DX,OFFSET MES
MOV AH,09H
INT 21H
MOV AX,BX
MOV CX,4
A3: PUSH CX
MOV CL,4
ROL AX,CL
POP CX
MOV BX,AX
AND AL,0FH
CMP AL,0AH
JB A2
ADD AL,07H
A2: ADD AL,30H
MOV DL,AL
MOV AH,02H
INT 21H
MOV AX,BX
LOOP A3
MOV AH,4CH
INT 21H
CODE ENDS
END START
四.实验结果并分析。
;显示提示信息 ;显示结果 11
五.收获体会。
在这一次代码转换的实验中,感觉自己在程序阅读和编写中较以前有了不错的提高。充分了解微机中的编码制及程序代码转换的基本思想,掌握将存储在内存单元中的十六进制数据转换成十进制和二进制显示在屏幕上的方法。由于以前练习不够,很多基本指令都是用的不熟练和恰当,增加了编程难度。通过实践来熟练操作是学以致用最好的方法。在debug的反复调试中,自己的调试水平得到了显著提高。在今后实验中加深其他方面诸如离了你只是的深入理解。
实验五、子程序及软中断程序设计
一. 实验内容
从PC机系统中断向量表的占用情况可见,42H~4FH是系
统未使用的中断向量,我们可利用它们开发用户自己软中断程序。
1.实验要求利用47H号中断将一组字符转换成16进制
数码,并在屏幕上显示出来。参见参考程序清单。
2. 编程求出一系列数据中的最大值、最小值,并送屏幕
显示。要求:①将求最大值和最小值程序的程序段编写为46H号软中断,利用46H号中断调用实现求最大值和最小值功能;
12
②将送屏幕显示用子程序实现。
二.分析设计思想
用户可将常用的具有特定功能的程序段编写成子程序使用。一般过程定义伪操作的格式为:
过程名 PROC Attribute
……
过程名 ENDP
Attribute是指类型属性,可以是NEAR或FAR,调用程序和过程在同一个代码段中使用NEAR,不在同一个代码段中,使用FAR。
1. 子程序段内调用与返回
(1)调用格式: CALL 过程名
(2)CPU执行CALL指令
首先将断口地址压入堆栈,为返回做准备,然后把子程序入口的有效地址→IP,从而转入子程序。
(3)返回指令: RET
在具有NEAR属性的子程序中,RET指令从栈顶弹出2个字节→IP,然后SP+2→SP。从而回到断点。
2. 软中断程序设计
(1)中断:
中断就是当系统运行或者程序运行期间在遇到某些特殊情况时,需CPU暂停执行现行程序,自动去处理随机事件,处理完毕后再返回被中断的程序,这一全过程称为中断。处理随机事件的程序, 13
就称为中断服务子程序。中断分为CPU中断(像除法错等)、软件中断(INT n指令而引发的中断)和硬件中断(由CPU以外的器件发出的中断请求信号而引发的中断)。
(2)中断向量
中断向量就是中断子程序的入口地址(由段基址CS和有效地址IP组成,占4个字节)存储在中断向量表中。微机系统中可以使用0—255共256个中断。当80×86系统工作在实模式时,内存的000H~3FFH被用作于中断向量表,向量表中包含了256个中断入口,参见表10-1,【表6】且在系统启动时由BIOS或DOS负责初始化。
(3)软中断程序设计
用户可自己开发中断服务程序,用它取代系统原有的服务程序,过程如下:
? 编写中断服务子程序,用IRET指令返回
? 确定使用的中断号n,修改中断向量表中4×n~4×n+3单元的对应中断服务程序入口
? INT n指令调用中断,此时CPU保护现场:将F、CS、IP寄存器入栈,然后从中断向量表中4×n~4×n+3单元取出n型中断向量写入IP,CS中,CPU根据CS:IP的值转向服务子程序。
? 当执行IRET时,恢复现场:从堆栈中弹出6个字节传送给IP、CS、F寄存器,回到断点继续执行。
? 程序结束返回DOS之前,要恢复系统的中断向量设置。 14
三. 程序清单及相关注解
;数码转换及显示:实验利用47H号中断将一组字符转换成16进制数码,并在屏幕上显示出来
DDATA SEGMENT
CSBAK DW ?
IPBAK DW ?
MKBAK DB ?
SW DW ?
MES DB ‘The data in buf1 are:’,0AH,0DH,’$’
BUF1DB 11H,22H,33H,44H,55H,66H,77H,88H,99H
DB 0AAH,0BBH,0CCH,0DDH,0EEH,0FFH,00H
DDATA ENDS
15
CODE SEGMENT
ASSUME CS:CODE,DS:DDATA START:
MOV
MOV
MOV
中断矢量
MOV
MOV
MOV
MOV
MOV
定义中断入口
CLD
STOSW
MOV
MOV
MOV
STOSW
MOV
MOV DX,OFFSET MES ;显示提示信息 AX,ES:[DI] CSBAK,AX AX,SEG MYINT ;保存原有CS ES,AX DI,4*47H AX,ES:[DI] IPBAK,AX ;保存原有IP AX,DDATA DS,AX AX,0 ;修改47H号中断的AX,OFFSET MYINT ;修改为用户自AH,09H
21H;显示BUF1中的内容
16 INT
MOV
MOV SI,OFFSET BUF1 CX,10H
INT 47H ;调用中断服务程序
MOV AX,0
MOV ES,AX
MOV DI,4*47H
MOV AX,IPBAK
CLD
STOSW
MOV AX,CSBAK
STOSW
MOV AH,4CH
INT 21H
MYINT PROC FAR ;自定义显示中断,入口参数为SI,CX
PUSH AX
PUSH DX
C1: MOV AL,[SI]
AND AL,0F0H
PUSH CX
MOV CL,4
17 ;恢复系统中断矢量 ;返回dos ;取高4位
SHR AL,CL
POP CX
CMP AL,0AH JB C2
ADD AL,07H
C2: ADD AL,30H MOV DL,AL MOV AH,02H INT 21H
MOV AL,[SI]
AND AL,0FH CMP AL,0AH JB C3
ADD AL,07H
C3: ADD AL,30H
MOV DL,AL MOV AH,02H INT 21H
INC SI
LOOP C1
POP DX
POP AX
18 ;是否是A以上的数 ;显示字符 ;取低4位 ;显示字符
IRET
MYINT ENDP
CODE ENDS
END START
五. 实验结果并分析。
;中断返回
六.收获体会。 在对汇编语言有了语法及基本程序设计思路的基础上,我们开始了理论的进一步学习。开始设计子程序及中断方面的设计实验。处理随机事件的程序,就称为中断服务子程序。二进制转换为16进制,从最低4位开始为1组,高位不足4个补0,没组换算一下合起来就是16进制的了,如1100011011:(0011)(0001)(1011)则16进制数为31BH或写成031BH十进制转换成16进制,就是十进制数除以16,直到商为0为止,将每次除的余数倒排,就是了。在程序中有较为抽象的地方不好理解,今后在这方面还需多多加强。
19
实验六、PC机内部8259中断及应用
一.实验内容
1.编写一键盘中断处理程序:
计算键盘中断次数,并用该程序替换系统键盘中断处理程序,使当按键8次(键盘中断产生16次)后,显示中断次数并结束应用。参见参考程序清单。
键盘中断处理的说明
当从键盘上键入一个键时,键盘上的处理器首先向微机产生硬件中断请求(IRQ1),然后将该键的扫描码传送给主机。而PC主机在IRQ1中断的作用下,调用09H型中断服务程序从键盘接口电路(口地址60H)读入扫描码,并转换成ASCII码,存入键盘缓冲区。
本实验置换系统的09H型中断服务程序,完成对键盘中断次数的统计。在该中断服务程序中,必须对键盘控制器(口地址61H)复位。复位键盘控制器只需读出端口61H的内容,并将最高位置1,再写入该端口。此外,按键按下和抬起均会引起中断,所以实际中断次数等于按键次数乘2。
修改上述程序,将按键的扫描码输出到屏幕上,并统计中断次数。
2.利用系统的1CH型中断(又称外扩的日时钟中断),编写程序,实现每隔2S在屏幕上显示一串字符“TIME TO!”,按任意键停止。
二. 分析设计思想
硬件中断是由CPU以外的器件发出的中断请求信号而引发的中断。80x86CPU只有两个引脚(INTR和NMI)可以接受外部的中断脉冲,为了管理众多的外部中断源,INTER公司设计了专用的配套芯片——8259A中断控制器
1. 8259A中断控制器简介
8259A中断控制器将中断源优先级排队、辨别中断源以及提供中断向量的电路于一片中,因此无需附加任何电路,只需对8259A进行编程,就可以管理8级中断,并选择优先模式和中断请求方式,即中断结构可以由用户编程来设置。同时,在不需增加其他电路的情况下,通过多片8259A的级连,能构成多达64级的矢量中断系统。8259A的内部结构和管脚如图11-1所示。
11-1
2. 8259A的中断过程,即微机系统响应可屏蔽中断的过程
20
(1)将加到引脚IR0~IR7上的中断请求寄存到中断请求寄存器中。
(2)在中断屏蔽寄存器的管理下,没有被屏蔽的中断请求被送到优先权电路判优。
(3)选中当前级别最高的中断源,然后从引脚INT向CPU发出中断请求信号。
(4)CPU满足一定的条件后,向8259A发出两个中断响应信号(负脉冲):
1)8259A从引脚INTA收到第1个中断响应信号之后,立即使中断服务寄存器中与被选中的中断源对应的那一位置1,同时把中断请求寄存器中的相应位清0。
2)从引脚INTA收到第2个中断响应信号之后,8259A把选中的中断源类型码n通过数据线送往CPU。
(5)在实模式下,CPU从4×n~4×n+3单元取出该中断源的中断向量→IP,CS,从而引导CPU执行该中断源的中断服务程序。
3. 8259A编程
(1)初始化编程
提供了4个(ICW1~ICW4)初始化命令字,写入命令寄存器组后,就建立了8259A的基本工作方式。系统8259A的初始化编程在微机启动时,由BIOS自动完成。用户不需再对其初始化,更改它的初始化设置。
BIOS对系统8259A初始化为:
?
?
?
? 中断触发方式采用边沿触发。 中断屏蔽方式采用常规屏蔽方式。 中断优先级的管理采用完全嵌套即固定优先级方式。IR0的请求级别最高,IR7的请求级别最低。 中断结束,采用常规结束方式。
(2)操作方式编程
将操作命令字OCW1~OCW3写入操作命令寄存器组,对中断处理过程实现动态控制。OCW1~ OCW3各命令格式如图11-2所示。
? OCW1——写中断屏蔽字(对奇地址操作)
?
? ? 某位Mi为1,表示对应的中断源IRQi被屏蔽;Mi为0,IRQi被开放。 OCW2——写中断方式命令字(对偶地址操作) ? 设置优先级是否进行循环,循环的方式及中断结束的方式。 OCW3——(对偶地址操作)
? 用来设置特殊屏蔽方式、查询方式
? 用来读8259A的中断请求寄存器IRR,中断服务寄存器ISR、中断屏蔽寄存器IMR
的当前状态。
21
4. PC机系统中8259A的应用 11-2 现代PC机系统中包含了两片8259A中断控制器,经级连可以管理15级硬件中断,但其中部分中断源已经被系统硬件占用,具体使用情况如表11-1所示。中断向量表的占用情况见表10-1。
两片8259A的端口地址为:主片在020H~03FH,实际使用020H和021H两个端口;从片在0A0H~0BFH范围,实际使用0A0H和0A1H两个端口。
11-
5. 8259A的应用编程流程,如图11-3所示。
开发用户中断时,做到以下几点:
(1)硬件方面:将外扩中断源的中断请求(由低电平到高电平的跃变)接入选定的中断源IRQi上。
(2)软件方面:
? 置换相应的中断向量,即把用户中断子程序的入口地址写入4×n~4×n+3单元。 ?
?
? 分别向主从8259A写入屏蔽字,使主片IMR的D2位置0;使从片IMR的Di位置0,开放用户中断。(即填写OCW1) 每一次中断服务结束,即执行IRET之前,向从片、主片8259A送中断结束命令。(即填写OCW2) 返回DOS之前,写中断屏蔽字OCW1,使主片IMR的D2位置1;使从片IMR的
Di位置1,屏蔽用户中断。恢复系统中断屏蔽字、恢复系统中断向量。
22
三.程序清单及相关注解
;按键8次,计算键盘中断次数
DATA SEGMENT
CSBAK DW ?
IPBAK
MKBAK DW ? DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START PROC FAR
MOV AX,DATA
MOV DS,AX
IN AL,21H
MOV
CLI
AND
OUT
MOV
MOV
MOV ;保留8259初始屏蔽字的状态 ;关中断 ;打开键盘屏蔽 ;修改键盘中断的中断矢量 MKBAK,AL 21h,AL AX,0 AL,11111101B ES,AX DI,24H ;IRQ1,09H,24H=09H*4
AX,ES:[DI]
IPBAK,AX ;写入IP
AX,OFFSET MYINT
23 MOV MOV MOV
CLD
STOSW
MOV
MOV
MOV
STOSW
XOR
A1: STI
CMP
JZ
JMP
A2: PUSH
CLI
MOV
MOV
MOV AX,ES:[DI] CSBAK,AX AX,SEG MYINT DX,DX ;写入CS ;清计数器 ;开中断 DX,10H ;是否按了8次键 ;是,结束程序运行 ;否则继续等待键盘中断 ;保存计数值 ;关中断 ;恢复系统中断矢量 A1 DX AX,0 A2 ES,AX DI,24H;IRQ1,09H
AX,IPBAK MOV
CLD
STOSW
MOV
STOSW AX,CSBAK
;恢复系统8259屏蔽字
;开中断 ;显示计数值 MOV AL,MKBAK OUT 21h,AL STI POP DX
CALL
MOV
INT
RET
START ENDP 21H SHWORD AX,4C00H
MYINT PROC FAR
STI ;开中断
;自定义键盘中断处理程序 INC DX IN AL,60H IN AL,61H
MOV AH,AL
OR AL,80H
OUT 61H,AL
CLI
MOV AL,61H
OUT 20H,AL ;计数加一 ;读入扫描码(用户可对此键值进行处理) ;读入控制字节 ;复位键盘 ;关中断 ;中断结束命令送中断控制器
IRET ;中断返回
MYINT ENDP
SHWORDPROC NEAR ;2→16进制显示 24
MOV CX,4
AGA: ROL DX,4
MOV AL,DL
AND AL,0FH
CMP AL,10
JC NEXT2
ADD AL,7
NEXT2: ADD AL,30H
MOV AH,0EH
INT 10H
LOOP AGA
RET
SHWORD ENDP
CODE ENDS
END START
六.收获体会。
本次试验中,对这次实验对中断特性和8259中断控制器的工作原理有了一定的理解,在实践操作中修改程序的时候没有把读入的扫描码AL传递到DL中,导致实验结果不对,最后在老师的指导下修改正确。对中断的理解在很多地方存在着认识不足,对于中断程序的设计还有待强化。希望可以加强对理论知识的认识逐步增强在这方面的实践能力。
实验七、PCI总线中断应用
一.实验内容
1.【示例】编写一实验程序,利用实验装置提供的中断源,完成每按动一次脉冲开关,产生一次中断,向显示器输出字符“7”。
2.修改示例程序,控制中断响应次数为10次,即当第11次以后按动脉冲开关,屏幕上不再显示“7”。
二. 分析设计思想
1.TD-PIT-B实验系统编程信息简要说明
(1).本实验的接口电路是在PD-PIT-B实验装置上搭接完成,而PC机作为主机控制该实验装置。二者之间通过PCI总线扩展卡及转接逻辑在PD-PIT-B实验装置上提供了一个仿真ISA的总线接口,用户可以基于该接口对常用接口芯片进行应用编程。TD-PIT-B实验系统的硬件环境,参见附录。
(2).要利用仿真ISA的总线接口资源,扩展接口电路,首先必须掌握实验装置获取的系统配置资源,即PCI总线资源配置的有关内容。
执行PCI_BIOS.EXE,获取实验用PCI总线扩展卡分配的地址空间及中断请求线。假设执行PCI_BIOS.EXE后屏幕显示:
25
从以上获取的信息可知道,本实验用的PCI总线扩展卡申请了:
? 4个I/O空间(最后一位为1来表示),其首地址分别是:0B800H,0BC00H,0C000H,
0C400H。
?
? 一个存储器空间(最后一位为0来表示),其首地址是:5000000H。 一个中断请求IRQ9
(3).确定TD-PIT-B实验装置中各接口电路所使用的端口地址
本系统中PCI配置空间的首地址是PCI总线扩展卡申请的第一个I/O空间(即BASE 0)。所以PCI各控制寄存器的地址定义为:
BASE 0的首地址0B800H + 各控制寄存器的偏移地址
而I/O部分实验使用的是PCI总线扩展卡申请的第三个I/O空间(即BASE 2)。各I/O接口芯片的端口地址定义为:
BASE 2的首地址0C000H + 各端口的偏移地址
2.实验说明及处理流程
本实验使用实验装置提供的中断请求信号IRQ,利用KK1的负脉冲作为中断源,每按一次KK1,在中断处理中完成字符“7”的显示。
使用实验装置提供的IRQ信号,除了要操作PC机的8259寄存器,还需要操作TD-PIT-PCI总线扩展卡上的控制寄存器“INTCSR”和“IMB4”,才可以实现中断的初始化、清除等。
? PCI_BIOS.EXE实验装置获取的系统配置资源,确定控制寄存器INTCSR(偏移38H~
3BH)和IMB4寄存器(偏移1FH)的端口地址:
BASE 0的首地址0B800H + 各控制寄存器的偏移地址
及中断号IRQ9。
? 初始化PCI中断
(1) 初始化INTCSR:向INTCSR的端口写入003F1F00H,即0B838H写00H,0B839H
写1FH,0B83AH写3FH,0B83BH写00H。
(2) 初始化中断向量:在修改中断入口地址时,建议先保存原来的入口地址。查表
7-1获得IRQ9对应的中断向量号为71H,中断入口地址即为01C4H,并将该地
址保存,替换为用户自己的中断服务程序入口地址。
(3) 设置PC机8259中断屏蔽寄存器,对应位为0,允许中断。21H中设置0~7号
屏蔽位,A1H中设置8~15号屏蔽位。同样保存原先的屏蔽位。IRQ9号中断须
? 将A1H中的位1置0。 清除实验用中断的中断源
(1) 清PCI板卡的中断标志:对IMB4寄存器的第3字节(IMB_BYTE3)做一读操
作,端口地址为0B81FH,然后向INTCSR第2字节(0B83AH)写入3FH。
(2) 清PC机8259中断标志:设置8259的OCW2,复位中断标志。(IRQ9中断向
A0H写入61H,向20H写入62H。)
(3) 退出程序返回DOS时恢复系统的初始化的设置:首先将保存的屏蔽命令字恢复
26
到屏蔽寄存器中,中断服务程序入口的段地址和偏移地址恢复到中断向量表中,? 然后返回DOS。 参考实验流程如图12-1所示。
三.程序清单及相关注解
;先执行PCI_BIOS.EXE,获得PCI板卡申请的第一个I/O空间的首地址及 ;中断号,修改下面CPU访问PCI操作寄存器的端口地址。
;由中断号确定相应中断向量及OCW1、OCW2命令字。
INTCSR_BYTE0 EQU 9438H ;修改PCI操作寄存器的端口地址 INTCSR_BYTE1 EQU 9439H
INTCSR_BYTE2 EQU 943AH
INTCSR_BYTE3 EQU 943BH
IMB4_BYTE3 EQU 941FH
DATA SEGMENT
CSBAK DW ?
IPBAK DW ?
MKBAK DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: CLI
MOV AX,DATA
MOV DS,AX ;初始化PCI寄存器
MOV DX,INTCSR_BYTE0
MOV AL,00H
OUT DX,AL
MOV DX,INTCSR_BYTE1
MOV AL,1FH
OUT DX,AL
27
MOV DX,INTCSR_BYTE2
MOV
OUT
MOV
MOV AL,3FH DX,AL DX,INTCSR_BYTE3 AL,00H
OUT DX,AL ;保存和替换中断入口地址
MOV AX,0000H
MOV ES,AX
MOV DI,01CCH ;INT 73H,01CCH=73H*4,根据中断号修改
MOV AX,ES:[DI]
MOV IPBAK,AX ;IP
MOV AX,OFFSET MYINT
CLD
STOSW
MOV AX,ES:[DI] ;CS
MOV CSBAK,AX
MOV AX,SEG MYINT
STOSW ;保存中断屏蔽字寄存器内容 IN AL,0A1H
MOV MKBAK,AL
AND AL,0F7H ;打开中断屏蔽位,根据中断号修改
OUT 0A1H,AL
STI ;等待
A1: NOP
CALL BREAK
JMP A1 ;========中断服务程序=========== MYINT: PUSH DS
PUSH AX
PUSH DX ;清PCI板中断标志
MOV DX,IMB4_BYTE3
IN AL,DX
MOV DX,INTCSR_BYTE2
MOV AL,3FH
OUT DX,AL;清8259中断标志
MOV AL,63H ;根据中断号修改
OUT 0A0H,AL
MOV AL,62H
OUT 20H,AL ;显示字符‘7’
MOV AH,0EH
MOV AL,37H
INT 10H
POP DX
POP AX
28
POP DS
IRET ;检测是否有键按下程序
BREAK PROC NEAR
PUSH DS
MOV AH,06H
MOV DL,0FFH
INT 21H
JE
POP RETURN DS
CLI ;恢复中断屏蔽命令字
MOV AL,MKBAK
OUT 0A1H,AL;恢复中断入口地址
MOV AX,0000H
MOV ES,AX
MOV DI,01CCH ;INT 73H,01CCH=73H*4,根据中断号修改
MOV AX,IPBAK
CLD
STOSW
MOV AX,CSBAK
STOSW
MOV DX,INTCSR_BYTE1
MOV AL,00H
OUT DX,AL
STI
MOV AX,4C00H
INT 21H
RETURN:POP DS
RET
BREAK ENDP
CODE ENDS
END START
四.收获体会。
实验中开始使用机箱并行接口操作,在DOS界面下操作。在老师已给的程序代码的基础上,修改端口地址,运行程序。对理论知识的认识还不够深刻,实际操作起来略显死板,也出现了些问题,比如端口地址修改不正确,连线没有一一对应等出现运行失败。在修改后才正常运行。今后除了加紧理论的学习为还需逐步完善自己的实践操作习惯,提高自己的学习能力。
实验八、8254定时计数器应用
一.实验内容
1.计数应用实验:编写程序,应用8254的计数功能,用开关模拟计数。使每当按动开关 29
KK1五次后,产生中断,并在屏幕上显示一个字符“M”。
2.定时应用:自己编写程序,应用8254的定时功能,将屏幕设计为一个秒表。
3.电子发声:自己编写程序让实验装置上的扬声器和PC机上的扬声器唱歌。
二.分析设计思想
(一)实验原理
8254是Intel公司生产的可编程间隔定时器。是8253的改进型,比8253具有更优良的性能。8254具有以下基本功能:
(1)有3个独立的16位计数通道;
(2)每个计数器可按二进制或十进制(BCD)计数;
(3)每个计数器可编程工作在6种不同工作方式;
(4)每个计数器允许的最高计数频率为10MNZ(8253为2MHZ);
(5)有读回命令(8253没有),可以读出当前计数单元的内容和状态寄存器内容;
13-
图13-1是8254的内部结构框图和管脚图。它是由与CPU的接口、内部控制电路和三个计数器组成。
三个独立的计数器,每个计数器的结构完全相同,如图13-2。
3个引角:GATEi——门控信号输入端
GA
图13-2 计数器结构示意图
1、工作过程:
(1) 初始化时,程序员将计数初值写入计数初值寄存器,自动送入16位减1计数器。计
数初值N=fCLKi÷fOUTi
(2) 当GATEi=1时,每一个CLKi信号的下降沿使减1计数器减1,锁存器随之变化。
(3) 当计数值减到规定值时,OUTi端产生输出信号。
2、8254的工作方式:
方式0——计数结束输出正跃变信号(可作为中断请求信号)
30
方式1——单脉冲发生器(形成负脉冲,宽度=N×CLK脉冲周期)
方式2——分频器(输出固定频率的脉冲)
图 13-3 方式2波形图 13-4 方式3计数值为奇数时的波形
方式3——方波发生器
方式4——软件触发的单脉冲发生器(输出负脉冲,宽度为一个CLK周期)
方式5——硬件触发的单脉冲发生器(输出负脉冲,宽度为一个CLK周期)
3、8254端口地址:
当=0时,地址总线的A1 A0组合(00~11),确定选择0#、1#、2#计数器及控制寄存器
A1A0=00,选中0# 计数器对应端口的偏移地址是: 40H
A1A0=01,选中1# 计数器 41H
A1A0=10,选中2# 计数器 42H
A1A0=11,选中控制寄存器
4、8254的控制字: 43H
读回控制字
方式控制字用来设置计数器的工作方式,其命令格式如表13-1所示。
读回控制字格式如表13-2所示。当读回控制字的D4位为0时,由该读回控制字D1~D2位指定的计数器的状态寄存器内容将被锁存到状态寄存器中。状态字格式如表13-3所示。 5、8254初始化编程步骤
一步:向控制寄存器写入控制字,确定使用的计数器及工作方式。
二步:向使用的计数器写入计数初值。
13-1
13-
001 = 选中计数器
31 0
13-3
(二)实验说明及步骤
1、确定8254端口地址
执行PCI_BIOS.EXE,获取实验用PCI总线扩展卡分配的地址空间及中断请求线。确定8254芯片所使用的端口地址:
本系统中I/O部分实验使用的是PCI总线扩展卡申请的第三个I/O空间(即BASE 2,假设为0C000H)。各I/O接口芯片的端口地址定义为:
BASE 2的首地址+ 各端口的偏移地址
8254端口的偏移地址定义为:
计数器0:40H 计数器1:41H 计数器2:42H 控制端口:43H
CPU访问8254端口地址为:
计数器0:0C040H 计数器1:0C041H
计数器2:0C042H 控制端口:0C043H
2、计数应用实验
编写程序,将8254的计数器0设置为方式3,计数值为十进制5,用微动开关KK1作为CLK0时钟,OUT0连接IRQ,每当KK1按动5次后产生中断请求,在中断服务程序中完成屏幕上显示字符“M”。参考接线图如图13-5所示。
实验步骤如下:
(1) 执行PCI_BIOS.EXE文件,确定实验装置中8254的各端口地址。按实验内容编写程
序(参考程序见后),编译、连接,生成执行文件。
(2) 设计实验线路图,完成线路连接。
(3) 打开实验箱电源,运行程序,按动KK1微动开关,观察是否按动5次后屏幕显示字
符“M”。
(4) 分析该程序结构,理解如何对8254初始化,如何实现中断服务。
(5) 修改计数初值,从而实现不同要求的计数。
13 –
3、定时应用实验——秒表的设计
32
设计思想:每计时1秒,描述时间的变量就应加1,并且每计时60秒自动归零。因此,可利用8254的计数器0设置为方式2,用实验箱提供的信号源10KHZ作为CLK0时钟,计数值为十进制0(即最大计数值10000),这样每隔1秒就会在OUT0端产生0到1的跃变,该信号接IRQ作为中断请求。在中断服务程序中完成对时钟的修改及显示。
实验步骤如下:
(1) 根据设计思想,设计实验线路图,完成线路连接。
(2) 画出程序流程图。
(3) 执行PCI_BIOS.EXE文件,确定实验装置中8254的各端口地址。自己编写程序,编
译、连接,生成执行文件。
(4) 打开实验箱电源,运行程序,观察屏幕的秒表显示是否正常。
4、电子发声实验
设计思想:向扬声器传送不同频率的方波,就能驱动小喇叭发出不同音符的音响。因此,设置8254的工作方式为方式3——方波频率发生器,改变8254计数通道i的计数初值,就可改变OUTi输出信号的频率,从而改变扬声器发出的音调。但每个音调发声的时间长短可以通过延时程序来控制。
1)用PC机内部的扬声器唱歌
在PC机内部集成了三个计数器,它们的功能、操作完全与8254兼容。三个计数器的端口地址分别为40H、41H、42H,控制寄存器地址为43H。但有各自专用功能:
? 通道0是系统的时钟节拍计时器。当计算机冷启动时,ROM BIOS对计数器编程以产生? 约每秒18.2个节拍的中断信号,即55ms向8259A(IR0)提出一次中断请求。 通道1专用于产生动态RAM的定时刷新信号。
? 通道2用来控制PC机扬声器的声音频率。
图13-6是PC机中定时器结构框图。
从图中可见扬声器是否发声受计数器2的输出端OUT2和端口61H的D0、D1位的共同控制,当三者都为1时,扬声器才可发声。因此,程序的设计思路是:(1)先将61H端口的D1、D0两位置1,打开扬声器;(2)设置计数器2为工作方式3;(3)由表8-4给出的每个音符对应的时间常数(即计数初值)分别送计数器2,以确定音调,使OUT0产生不同频率的方波,从而改变扬声器发声的音调。(4)程序退出时恢复端口61H原来的值。
13-6
实验步骤如下:
(1) 分析参考程序,画出程序流程图。
(2) 编写程序,编译、连接,生成执行文件。
33
(3) 打开实验箱电源,运行程序,聆听音乐。
(4) 若音乐节拍发生时间较长或较短,可以修改延时子程序的计数值,调整发声时间到
最佳。
2)用实验系统扬声器唱歌
用信号源1MHZ作为扬声器发声基准时钟接8254的CLK0,计数器0设置为工作方式3,由表8-4给出的每个音符对应的时间常数(即计数初值)分别送计数器0,以确定音调,OUT0产生不同频率的方波连接扬声器SPK端子驱动扬声器产生音乐。
实验步骤如下:
(1) 根据设计思想,设计实验线路图,完成线路连接。
(2) 画出程序流程图,自己编写程序。
(3) 执行PCI_BIOS.EXE文件,确定实验装置中8254的各端口地址。编辑程序,编译、
连接,生成执行文件。
(4) 打开实验箱电源,运行程序,聆听音乐。
(5) 若音乐节拍发生时间较长或较短,可以修改延时子程序的计数值,调整发声时间到
最佳。
四.收获体会。
在最后一次微机原理实验中,总结了以前实验的不足和教训, 8254定时计数器应用实验中,进行得比较顺利,验证了准确结果,能比较熟练的操作DOS界面,对程序的代码有一定的认识。机箱的连接过程,比较复杂,但注意出和如并行线上的一一对应。对理论也有家了较为清晰的认识。