计算机硬件技术基础学习知识实验规范标准答案程序.doc
-!实验一:简单程序设计实验(1)编写一个 32 位无符号数除法的程序,要求将存放在 NUM1 中的 32 位无符号数与存放 在 NUM2 中的 16 位无符号数相除,结果存放在 NUM3 和 NUM4 中。程序流程图略。 参考源程序:DATASEGMENTNUM1 DD 2A8B7654H NUM2 DW 5ABCH NUM3 DW ?NUM4 DW ? DATAENDSCODESEGMENTASSUME DS:DATA, CS:CODESTART: MOV AX,DATA;数据段寄存器初始化MOV DS,AXMOV AX, WORD PTR NUM1MOV DX, WORD PTR NUM1+2DIV NUM2MOV NUM3,AX MOV NUM4,DXMOV AH,4CH;正常返回DOS系统INT 21H CODEENDSEND START(2)编写一个拆字程序。要求将存放在 ARY 单元的 2 位十六进制数 X1X2 拆为 X1 和 X2 两 部分,并以 0X1 和 0X2 的形式分别存入 ARY+1 和 ARY+2 单元中。程序流程图略。 参考源程序:DATASEGMENT ARY DB 2AH,?,?DATAENDSCODESEGMENTASSUME DS:DATA, CS:CODE START: MOV AX,DATAMOV DS,AXMOV SI,OFFSET ARY;取ARY的偏移地址MOV AL,SI;取16进制数至ALMOV BL,ALAND AL,0F0H;取16进制数的高四位,即X1SHR AL,4MOV SI+1,AL;存0X1MOV AL,BLAND AL,0FH;取16进制数的低四位,即X2MOV SI+2,AL;存0X2MOV AH,4CH INT 21HCODEENDSEND START实验二:分支程序设计实验(1)编写一个字符比较程序,比较 3 个无符号字节数 A,B,C 的大小,并根据比较结果 对变量 K 赋值:如果 3 个数不相等,则 K=0;如果 3 个数中有两个相等,则 K=1; 如果 3 个数都相等,则 K=2。程序流程图略。 参考源程序:DATASEGMENT;定义待比较数A、B、C,比较结果KA DB 20H B DB 20H C DB 20H K DB ?DATAENDSCODESEGMENTASSUME CS:CODE,DS:DATA START: MOV AX,DATAMOV DS,AX MOV AL,ACMP AL,B;对A、B进行比较,不相等则转到COMP2JNE COMP2;相等则比较A、CCMP AL,CJNE K1;A、C不相等则K=1JMP K2;A、C相等则K=2COMP2: MOV BL,B CMP BL,CJE K1;对B、C进行比较,相等则K=1CMP AL,CJE K1;对A、C进行比较,相等则K=1K0:MOV K,0JMP EXIT K1:MOV K,1JMP EXIT K2:MOV K,2EXIT:MOV AH,4CHINT 21HCODEENDSEND START(2)编写一个能实现下列表达式的程序:N = A + BA B设 A,B,C 为小于 128 的正整数。 A B + C程序流程图略。 参考源程序:DATASEGMENTA BA DB 22H;定义 A、B、C、N B DB 10HC DB 01H N DB ?DATAENDSCODESEGMENTASSUME CS:CODE, DS:DATA START: MOV AX,DATAMOV DS,AXMOV AL, A CMP AL, BJG CALCUL;A 小于或等于 B 则 N=A+BADD AL,B JMP EXITCALCUL: SUB AL, B ADC AL, CEXIT:MOV N, AL MOV AH,4CH INT 21HCODEENDSEND START实验三 循环程序设计实验(1)将字符串STRN(以“$”结尾)中的每一个字符均加上偶校验位,并统计有多少个字符 因含有奇数个“1”而加上了校验位。统计结果存于N单元中。程序流程图略。 参考源程序:DATASEGMENTSTRN DB What$;任意定义一个字串,以“$”结尾COUNT EQU $-STRN N DB ?BUF DB COUNT DUP(?) DATAENDSCODESEGMENTASSUME CS:CODE, DS:DATA START:MOV AX, DATAMOV DS, AX MOV AX, DATA MOV ES, AXLEA SI, STRN LEA DI, BUFMOV CX, COUNT MOV AL, 0LP1:MOV BL, SI;逐个取字符进行判断AND BL, BL;自己和自己做与运算JP NEXT;根据 PF 标志位的变化进行跳转INC ALORBL, 80H NEXT:MOV DI, BLINC SI INC DI LOOP LP1MOV N, AL MOV AH, 4CHINT 21HCODEENDSEND START(2)在 FIRST 开始的一片连续的数据区中存放着 100 个数据,编写一个程序,统计第 1个数据0之前的数据个数。 程序流程图略。 参考源程序:DATASEGMENTFIRST DB 10H,24H,34H, 73H,20H,44H,03H,36H,41H;任取 9 个数做演示COUNT EQU $-FIRST NUM DB ?DATAENDSCODESEGMENTASSUME CS:CODE, DS:DATA START:MOV AX,DATAMOV DS,AXMOV DL, 0;计数值初始为 0MOV CX,COUNTMOV BX, OFFSET FIRSTLP1:MOV AL, BX;每次取一个数,与 0 比较CMP AL, 00H JNE NEXTJMP EXIT;找到 0 则退出NEXT:INC DL;没找到 0 则计数值加 1INC BX LOOP LP1EXIT:MOV NUM, DL MOV AH, 4CH INT 21HCODEENDSEND START实验四:子程序设计实验将BUF开始的10个单元中两位十六进制数转换成ASCII码,并在屏幕上显示出来。要求码型 转换通过子程序HEXASC实现,参数传送采用寄存器传送方式。程序流程图略。 参考源程序: (1)实现方法一:远过程调用 DATA SEGMENTBUF DB 10H,2FH,0D0H,0FEH,33H,0F0H,20H,10H,3DH,0A2HCOUNT EQU $-BUF;定义任意长度的一段 BUF DATA ENDSSTACK1 SEGMENT STACKDB 100 DUP(?);设置足够深度的栈区STACK1 ENDSCODESEGMENTASSUME CS:CODE,DS:DATA,SS:STACK1START:MOV AX,DATA MOV DS,AXMOV SI,OFFSET BUF MOV CX,COUNTAGAIN:MOV AL,SI;逐个取数MOV BL,ALSHR AL,4AND AL,0FH;先对高字节部分转换(寄存器 AL 传参)CALL FAR PTR HEXASC;调用子程序MOV DL,ALMOV AH,02H;显示高字节部分对应的字符INT 21HMOV AL,BLAND AL,0FH;再对低字节部分转换(寄存器 AL 传参)CALL FAR PTR HEXASC;调用子程序MOV DL,ALMOV AH,02H;显示低字节部分对应的字符INT 21HMOV DL,20HMOV AH,02H;显示空格INT 21HINC SILOOP AGAINMOV AH,4CH INT 21HCODEENDSCODEBSEGMENT ASSUME CS:CODEBHEXASCPROC FARCMP AL,09H;判断是不是数字JA HEXATOF;是字母则转到 HEXATOFADD AL,30H;是数字则对应到数字的 ASCII 码JMP ENDHEXHEXATOF:ADD AL,37H;是字母则对应到字母的 ASCII 码ENDHEX: RET HEXASC ENDP CODEBENDSEND START(2)实现方法二:近过程调用DATA SEGMENTBUF DB 10H,2FH,0D0H,0FEH,33H,0F0H,20H,10H,3DH,0A2HCOUNT EQU $-BUF;定义任意长度的一段 BUF DATA ENDSSTACK1 SEGMENT STACKDB 100 DUP(?);设置足够深度的栈区STACK1 ENDSCODESEGMENTASSUME CS:CODE,DS:DATA,SS:STACK1START:MOV AX,DATA MOV DS,AXMOV SI,OFFSET BUF MOV CX,COUNTAGAIN:MOV AL,SI;逐个取数MOV BL,ALSHR AL,4AND AL,0FH;先对高字节部分做转换CALL HEXASCMOV DL,AL;显示高字节部分对应的字符MOV AH,02H INT 21HMOV AL,BLAND AL,0FH;再对低字节部分做转换CALL HEXASCMOV DL,AL;显示低字节部分对应的字符MOV AH,02H INT 21HMOV DL,20H;显示空格MOV AH,02H INT 21HINC SI;继续循环或退出LOOP AGAINMOV AH,4CH INT 21HHEXASCPROC NEAR CMP AL,09HJA HEXATOF ADD AL,30H JMP ENDHEXHEXATOF:ADD AL,37H ENDHEX: RETHEXASCENDPCODEENDSEND START实验五:DOS 中断调用实验(1)如果从键盘上依次输入的是一个数字和一个字母,则输出“RIGHT”标记后结束程序, 否则输出标记“ERROR”后转向原出错处重做。试编程实现该功能。程序流程图略。 参考源程序:DATASEGMENTMSG DB 0AH,0DH,RIGHT,0AH,0DH,$ WRN DB 0AH,0DH,ERROR,0AH,0DH,$DATAENDSCODESEGMENTASSUME CS:CODE, DS:DATA START:MOV AX,DATAMOV DS,AXAGAIN:MOV AH,01H;等待用户输入 1 个字符并显示INT 21HCMP AL,39H JA EMSG CMP AL,30HJB EMSG;判断输入是否是数字,不是则报错MOV AH,01H;等待用户输入 1 个字符并显示INT 21H CMP AL,A JB EMSGCMP AL,Z;判断输入是否是大写字母,不是则继续JB EXIT;判断是不是小写字母CMP AL,a JB EMSG CMP AL,zJB EXIT;不是字母则报错,是字母则转到 EXITEMSG:LEA DX,WRN MOV AH,09H INT 21HJMP AGAINEXIT:MOV DX,OFFSET MSGMOV AH,09H;显示“RIGHT”并退出INT 21HMOV AH,4CHINT 21H CODEENDSEND START(2)编写一程序分类统计字符个数:即接收键入的一串字符(字符个数不超过50个,该字 符串用回车作为结束),并按数字、字母和其它字符分类计数,然后将结果存入digit、letter 和other 3个存储单元中,并显示结果。程序流程图略。 参考源程序:DATASEGMENTMSG1 DB 0AH, 0DH, Number of digit:,20H,$ MSG2 DB 0AH, 0DH, Number of letters:, 20H,$MSG3 DB 0AH, 0DH, Number of other characters:, 20H, $ BUF DB 50DB 0DB 50 DUP(?);设置足够深的栈区DIGIT DB ? LETTER DB ? OTHER DB ?DATAENDSSTACK1SEGMENT STACK DB 100 DUP(?)STACK1ENDSCODESEGMENTASSUME CS:CODE,DS:DATA,SS:STACK1START:MOV AX,DATA MOV DS,AXMOV AH,0AH;等待用户输入字符串并显示MOV DX,OFFSET BUF INT 21HMOV SI, OFFSET BUF MOV CL,SI+1MOV CH,00H MOV AL,00H MOV AH,00H MOV BH,00HAGAIN:MOV BL,SI+2 CMP BL,30HJB OTH;ASCII 码小于 30H 则归类为“其它”CMP BL,3AHJB DIG;ASCII 码大于等于 30H 小于 3AH 则归类为“数字” CMP BL,41HJB OTH;ASCII 码大于等于 3AH 小于 41H 则归类为“其它” CMP BL,5BHJB LET;ASCII 码大于等于 41H 小于 5BH 则归类为“字母” CMP BL,61HJB OTH;ASCII 码大于等于 5BH 小于 61H 则归类为“其它” CMP BL,7BHJB LET;ASCII 码大于等于 61H 小于 7BH 则归类为“字母”OTH:INC AL;“其它”计数器加 1DIG:JMP ENDLP INC AH;“数字”计数器加 1LET:JMP ENDLP INC BH;“字母”计数器加 1ENDLP:INC SILOOP AGAIN;继续循环MOV LETTER, BH MOV OTHER, ALMOV DX, OFFSET MSG1MOV AH,09H INT 21HMOV AL, DIGIT CALL DISP;显示“数字”有多少个MOV DX, OFFSET MSG2MOV AH,09H INT 21HMOV AL, LETTER CALL DISP;显示“字母”有多少个MOV DX, OFFSET MSG3MOV AH,09H INT 21HMOV AL, OTHER CALL DISP;显示“其它”有多少个MOV AH,4CH INT 21HDISPPROC NEAR;显示子程序MOV DIGIT, AH;统计各类个数MOV AH,00H MOV DH,0AH DIV DHMOV CH,AH ADD AL, 30H MOV DL, AL MOV AH, 02H INT 21HADD CH,30H MOV DL, CH MOV AH, 02H INT 21HRET DISPENDPCODEENDSEND START实验六:扩展定时器/计数器接口实验(1)计数器0工作于方式3,编写初始化程序,观察其输出OUT0信号的波形。修改计数初 值,观察OUT0信号的变化情况。 硬件连接方法:8254计数器0的CLK0端接规则的脉冲输入(频率自选),OUT0接示波器的 正极;示波器负极接地。程序流程图略。 参考源程序:DATA SEGMENTDB 100 DUP(?) DATA ENDSCODESEGMENTASSUME CS:CODE, DS:DATA START: MOV AX,DATAMOV DS,AXMOV DX,20FH;写入计数器0的控制字MOV AL,00010110B OUT DX,ALMOV DX,20CH;写入计数器0的计数初值MOV AL,05H OUT DX,ALMOV AH,4CH INT 21HCODEENDSEND START(2)将计数器1和计数器0级联起来,二者均工作于方式3,编写初始化程序,观察OUT1 和OUT0信号的波形,说明二者的关系。修改计数初值,观察OUT0和OUT1输出波形的变 化情况。 硬件连接方法:8254计数器1的CLK1端接规则的脉冲输入(频率自选),OUT1接8254计数 器0的CLK0,计数器0的输出OUT0接示波器正极;示波器负极接地。程序流程图略。 参考源程序:DATASEGMENT DB 100 DUP(?)DATAENDS CODESEGMENTASSUME CS:CODE,DS:DATA START: MOV AX,DATAMOV DS,AXMOV DX,20FHMOV AL,00010110B;写入计数器0的控制字OUT DX,ALMOV DX,20CH;写入计数器0的计数初值MOV AL,05H OUT DX,ALMOV DX,20FHMOV AL,01010110B;写入计数器1的控制字OUT DX,ALMOV DX,20DH;写入计数器1的计数初值MOV AL,02H OUT DX,ALMOV AH,4CH INT 21HCODEENDSEND START实验七:并行输入/输出接口 8255A 简单编程实验(1)利用 8255A 的 B 口输出控制两组发光二级管 L1,L3,L5,L7 和 L2,L4,L6,L8 亮灭交替变 化。分析:按照题目要求,当 8255A 的 B 口输出为 01010101B(55H)时,发光二极管 L1,L3,L5,L7 会被点亮,当 8255A 的 B 口输出为 10101010B (0AAH)时,发光二极管 L2,L4,L6,L8 会被点 亮。因此,通过延时改变 8255A 的 B 口输出,即可实现两组发光二极管的亮灭交替变化。 由于 LED 随时出于准备好的状态,因此 8255A 的 B 口可工作于方式 0 输出,其它端口未使 用,无需考虑。因此,8255A 的方式控制字为:10000000B(80H)。硬件连接方法:8255A 的 B 口 PB0PB7 分别连接 L1L8。 程序流程图略。参考源程序:.486DATASEGMENTPORTA DW 208H;8255A端口A地址 PORTB DW 209H;8255A端口B地址 PORTC DW 20AH;8255A端口C地址 PORT_CTR DW 20BH;8255A控制端口地址DATAENDSSTACK1 SEGMENT STACK DB 100 DUP(?)STACK1 ENDSCODESEGMENTASSUME CS:CODE, DS:DATA, SS:STACK1START: MOV AX,DATA MOV DS,AXMOV DX, PORT_CTR MOV AL, 10000000B;8255A初始化;控制字OUT DX, ALMOV DX, PORTB MOV AL, 00H OUT DX, AL;8255A端口B清零,LED初始化(全灭)LP0:MOV BL, 01010101B MOV AL, BLOUT DX, AL CALL DELAYNOT ALMOV BL, ALMOV AH, 01H;调用BIOS的16H功能判断键盘是否有输入INT 16H JNZ EXIT JMP LP0EXIT:MOV AH, 4CH INT 21HDELAYPROC NEAR;延时子程序(可通过修改NOP指令数量改变延时时间) MOV ECX, 0FFFFFFFHLP2:NOPLOOPD LP2RET DELAYENDPCODEENDSEND START(2)利用 8255A 的 A 口读入 8 个开关 K1K8 的状态,当只有 K1 合上时,L1L8 显示00000001B;当只有 K1 和 K2 合上时,L1L8 显示 00000010B;当只有 K1,K2 和 K3 合上 时,L1L8 显示 00000011B;当只有 K1,K2,K3 和 K4 合上时,L1L8 显示 00000100B; 直到所有开关合上时,L1L8 显示 00001000B,并结束程序的运行。发光二极管的状态通 过 8255A 的 B 口进行控制。分析:按照题目要求,可以通过查询的方式读取 8255A 的 B 口状态,并根据查询的结果给 A 口送出相应数据,A 口工作在方式 0 的输入状态,B 口工作在方式 0 输出状态,C 口不需要 考虑,所以 8255A 的方式控制字为:10010000B)硬件连接方法:(1)8255A 的 A 口 PA0PA7 对应连接 K1K8;(2)8255A 的 B 口 PB0PB7 对应连接 L1L8; 源代码:DATASEGMENTLISTDB 01H, 03H, 07H, 0FH, 1FH, 3FH, 7FH, 0FFH DATAENDSSTACK1 SEGMENT STACK DB 100 DUP(?)STACK1 ENDSCODESEGMENTASSUME CS:CODE, DS:DATA, SS:STACK1START: MOV AX, DATAMOV DS, AXMOV DX, 20BH;8255A初始化MOV AL, 10010000B OUT DX, ALMOV DX, 209H;8255A的B口清零,LED初始化(全灭) MOV AL, 00HOUT DX, ALL0:MOV DX, 208H;读8255A的A口,获得开关状态IN AL, DXMOV BL, 00H MOV CX, 8MOV SI, OFFSET LIST L1:INC BLCMP AL, SI JZ FIND INC SILOOP L1JMP L0FIND:MOV AL, BL MOV DX, 209H;当前开关状态为表中所列状态之一;显示LED状态OUT DX, AL CMP AL, 08H JNZ L0MOV AH, 4CH INT 21HCODEENDSEND START实验八:并行输入/输出接口 8255A 综合应用实验(1)利用8254计数器0、计数器1和8255A的B口实现对发光二极管的定时控制,让8个发光 二极管每隔1s从左到右依次点亮。(要求计数器1的时钟脉冲频率为250kHz)。分析: 根据题目要求,需要利用8254进行定时1s控制,定时到后,改变8255A的B口输出。可以利用中断的方式实现,8254定时到时向CPU申请中断,CPU相应中断后在中断程序中改变8255A的B口输出。 由于题目要求8254的输入脉冲频率为250kHz,所以需要级联计数器1和计数器0实现1s定时(参考程序中利用计数器1进行20ms定时,计数器0进行50次计数,计数次数到时由OUT0 向CPU申请中断)。8255A的B口控制LED,可工作在方式0输出,A口未使用,为了选通实 验板上的中断输入C口的PC7须输出低电平,因此C口的高四位工作在方式0输出。综合上述 要求,8254和8255A的初始化参数为:8254计数器1的计数初值为:N=20ms/4s=5000D;方式控制字为:01110100B (74H)8254计数器0的计数初值为:N=50D;方式控制字为:00010100B (14H)8255A的方式控制字:10000000B (80H);C口按位置位/复位控制字:00001110B (0EH)(使PC7复位,允许8254的OUT0中断到达系统8259的IRQ3端)此外,利用中断方式实现题目要求的功能还需要设置系统8259芯片的中断屏蔽字和系统 存储器中的中断向量表(修改中断类型号为0BH的中断向量)。硬件连接方法:(1)250kHz脉冲输出接8254的CLK1,OUT1接CLK0,OUT0接IRQ;(2)8255A的B口PB0PB7对应连接L1L8。DATASEGMENTPORT0 DW 20CH;8254计数器0端口地址PORT1 DW 20DH;8254计数器1端口地址PORT2 DW 20EH;8254计数器2端口地址PORT3 DW 20FH;8254控制寄存器端口地址PORTA DW 208H;8255A的A口端口地址PORTB DW 209H;8255A的B口端口地址PORTC DW 20AH;8255A的C口端口地址DATAPORT_CTR DW 20BH ENDS;8255A的控制寄存器端口地址程序流程图略。 参考源程序:STACK1 SEGMENT STACK DB 100 DUP(0)STACK1 ENDSCODESEGMENTASSUME CS:CODE, DS:DATA, ES:DATA, SS:STACK1START: MOV AX, DATA MOV DS, AX MOV ES, AXMOV AL, 80H; 8255初始化, B口方式0输出,C口高4位输出MOV DX, PORT_CTR OUT DX, ALMOV AL, 0EH;PC7清零,允许8254中断到IRQ3OUT DX, ALMOV AL, 00H;发光二极管初始化(全灭) MOV DX, PORTBOUT DX, ALMOV AX, 350BH;保存系统原有0BH号中断的中断向量至堆栈INT 21H PUSH ES PUSH BXMOV AX, SEG INTPROC MOV DS, AXMOV DX, OFFSET INTPROCMOV AX, 250BH;将程序要求的中断向量写入INT 21HIN AL, 21H;设置8259的IMR寄存器,允许IRQ3中断AND AL, 0F7H OUT 21H, ALSTI;开中断,CPU可以响应外部可屏蔽中断MOV DX, PORT3;8254计数器0初始化MOV AL, 14H OUT DX, ALMOV DX, PORT0;计数器0写入计数初值50DMOV AL, 50D OUT DX, ALMOV DX, PORT3;8254计数器1初始化MOV AL, 74H OUT DX, ALMOV DX, PORT1;计数器1写入计数初值5000DMOV AX, 5000D OUT DX, AL MOV AL, AH OUT DX, ALMOV BH, 80H;BH存放当前8255A的B口输出MOV AL, BHMOV DX, PORTB;8255A的B口输出OUT DX, ALWAIT0:NOP NOP NOPMOV AH, 01H;判断键盘上是否有键按下,若有则结束程序INT 16H JNZ EXIT JMP WAIT0EXIT:POP DX;恢复中断向量表中的原有0BH号中断向量POP DSMOV AX, 250BH INT 21HMOV AH, 4CH INT 21HINTPROC PROC NEAR MOV AL, BH ROR AL,1MOV BH, ALMOV DX, PORTB;向8255A的B口写出数据,点亮对应LED OUT DX, ALMOV AL, 20H;向8259发出中断结束命令OUT 20H, AL IRETINTPROC ENDP CODEENDSEND START(2)8255A的A口与8个开关相连,工作于方式1下,要求:利用当前的开关状态通过B口控 制L1L8的亮或灭。A口的/STBA选通信号由按键K发出,每按一次K键,读入当前开关状态。 分析:8255A的B口用来控制LED的亮灭,可工作在方式0下。 根据题意,可以通过查询方式不断读取8255A的C口状态确定K键是否按下,也可以利用中断方式,当K键按下时,由INTRA(PC3)向CPU申请中断。当判断K键按下后,读取8255A的A口状态,并通过B口显示到LED上。利用查询方式实现时,仅需要给定方式选择 控制字;利用中断方式实现时,除控制字外还需设定INTEA为1,允许INTRA申请中断。因此,8255A的方式控制字为:10110000B(0B0H);使 INTEA(PC4)置1,其控制字为00001001B(09H)。注意:利用中断方式实现时还需要置PC7为0,使INTRA能到达8259的IRQ3硬件连接与参考源程序:(1)利用查询方式实现 硬件连接:1)8255A的A口PA0PA7与K1K8对应相连;2)8255A的B口PB0PB7与L1L8对应相连;3)按键K接8255A的C口PC4。 参考源程序:CODESEGMENT ASSUME CS:CODESTART: MOV AL, 0B0H; 8255A初始化,方式控制字10110000BMOV DX, 20BH OUT DX, ALMOV DX, 209H;LED初始化MOV AL, 00H OUT DX, ALAGAIN:MOV AH, 01H;判断计算机键盘上是否有键按下,若有结束程序INT 16H JNZ EXITMOV DX, 20AH;读入8255A的C口状态IN AL, DXTEST AL, 00010000B;判断PC4=1?(K键是否按下) JNZ AGAINMOV DX, 208H;读入8255A的A口状态IN AL, DXMOV DX, 209H;将A口状态送8255A的B口OUT DX, AL JMP AGAINEXIT:MOV AH, 4CH INT 21HCODEENDSEND START(2)利用中断方式实现 硬件连接:1)8255A的A口PA0PA7与K1K8对应相连;2)8255A的B口PB0PB7与L1L8对应相连;3)按键K接8255A的C口PC4;4)8255A的C口PC3(INTRA)接IRQ。 参考源程序:DATASEGMENTPORTA DW 208H; 8255A的A口地址PORTB DW 209H; 8255A的B口地址PORTC DW 20AH; 8255A的C口地址DATAPORT_CTR DW 20BH ENDS; 8255A的控制口地址STACK1 SEGMENT STACKDB 100 DUP(0) STACK1 ENDSCODESEGMENTASSUME CS:CODE, DS:DATA, ES:DATA, SS:STACK1START: MOV AX, DATA MOV DS, AX MOV ES, AXMOV DX, PORT_CTR;写入8255A方式控制字0B0H MOV AL, 0B0HOUT DX, ALMOV AL, 09H;写入C口按位置位控制字,PC4置“1”OUT DX, ALMOV AL, 0EH;写入C口按位复位控制字,PC7置“0”,开IRQ OUT DX, ALMOV AX, 350BH;保存系统原有中断号为0BH的中断向量到堆栈INT 21H PUSH ES PUSH BXMOV AX, SEG INTPROC;向0BH号中断写入新的中断向量MOV DS, AXMOV DX, OFFSET INTPROC MOV AX, 250BHINT 21HIN AL, 21H;允许8259的IRQ3中断AND AL, 0F7H OUT 21H, ALSTI;允许CPU响应可屏蔽中断WAIT0:MOV AH, 01H;判断是否有键按下,若有则结束程序,若无则等待INT 16H JZ WAIT0POP DX;恢复系统中断向量表POP DSMOV AX, 250BH INT 21HMOV AH, 4CH INT 21HINTPROC PROC NEARMOV DX, PORTA;读入8255A端口A的状态(开关
收藏
- 资源描述:
-
-!
实验一:简单程序设计实验
(1)编写一个 32 位无符号数除法的程序,要求将存放在 NUM1 中的 32 位无符号数与存放 在 NUM2 中的 16 位无符号数相除,结果存放在 NUM3 和 NUM4 中。
程序流程图略。 参考源程序:
DATA SEGMENT
NUM1 DD 2A8B7654H NUM2 DW 5ABCH NUM3 DW ?
NUM4 DW ? DATA ENDS
CODE SEGMENT
ASSUME DS:DATA, CS:CODE
START: MOV AX,DATA ;数据段寄存器初始化
MOV DS,AX
MOV AX, WORD PTR NUM1
MOV DX, WORD PTR NUM1+2
DIV NUM2
MOV NUM3,AX MOV NUM4,DX
MOV AH,4CH ;正常返回DOS系统
INT 21H CODE ENDS
END START
(2)编写一个拆字程序。要求将存放在 ARY 单元的 2 位十六进制数 X1X2 拆为 X1 和 X2 两 部分,并以 0X1 和 0X2 的形式分别存入 ARY+1 和 ARY+2 单元中。
程序流程图略。 参考源程序:
DATA SEGMENT ARY DB 2AH,?,?
DATA ENDS
CODE SEGMENT
ASSUME DS:DATA, CS:CODE START: MOV AX,DATA
MOV DS,AX
MOV SI,OFFSET ARY ;取ARY的偏移地址
MOV AL,[SI] ;取16进制数至AL
MOV BL,AL
AND AL,0F0H ;取16进制数的高四位,即X1
SHR AL,4
MOV [SI+1],AL ;存0X1
MOV AL,BL
AND AL,0FH ;取16进制数的低四位,即X2
MOV [SI+2],AL ;存0X2
MOV AH,4CH INT 21H
CODE ENDS
END START
实验二:分支程序设计实验
(1)编写一个字符比较程序,比较 3 个无符号字节数 A,B,C 的大小,并根据比较结果 对变量 K 赋值:
如果 3 个数不相等,则 K=0;
如果 3 个数中有两个相等,则 K=1; 如果 3 个数都相等,则 K=2。
程序流程图略。 参考源程序:
DATA SEGMENT ;定义待比较数A、B、C,比较结果K
A DB 20H B DB 20H C DB 20H K DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA START: MOV AX,DATA
MOV DS,AX MOV AL,A
CMP AL,B ;对A、B进行比较,不相等则转到COMP2
JNE COMP2 ;相等则比较A、C
CMP AL,C
JNE K1 ;A、C不相等则K=1
JMP K2 ;A、C相等则K=2
COMP2: MOV BL,B CMP BL,C
JE K1 ;对B、C进行比较,相等则K=1
CMP AL,C
JE K1 ;对A、C进行比较,相等则K=1
K0: MOV K,0
JMP EXIT K1: MOV K,1
JMP EXIT K2: MOV K,2
EXIT: MOV AH,4CH
INT 21H
CODE ENDS
END START
(2)编写一个能实现下列表达式的程序:
⎧
N = ⎨
A + B
A ≤ B
设 A,B,C 为小于 128 的正整数。
⎩ A − B + C
程序流程图略。 参考源程序:
DATA SEGMENT
A > B
A DB 22H ;定义 A、B、C、N B DB 10H
C DB 01H N DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA START: MOV AX,DATA
MOV DS,AX
MOV AL, A CMP AL, B
JG CALCUL ;A 小于或等于 B 则 N=A+B
ADD AL,B JMP EXIT
CALCUL: SUB AL, B ADC AL, C
EXIT: MOV N, AL MOV AH,4CH INT 21H
CODE ENDS
END START
实验三 循环程序设计实验
(1)将字符串STRN(以“$”结尾)中的每一个字符均加上偶校验位,并统计有多少个字符 因含有奇数个“1”而加上了校验位。统计结果存于N单元中。
程序流程图略。 参考源程序:
DATA SEGMENT
STRN DB What$ ;任意定义一个字串,以“$”结尾
COUNT EQU $-STRN N DB ?
BUF DB COUNT DUP(?) DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA START: MOV AX, DATA
MOV DS, AX MOV AX, DATA MOV ES, AX
LEA SI, STRN LEA DI, BUF
MOV CX, COUNT MOV AL, 0
LP1: MOV BL, [SI] ;逐个取字符进行判断
AND BL, BL ;自己和自己做与运算
JP NEXT
;根据 PF 标志位的变化进行跳转
INC AL
OR BL, 80H NEXT: MOV [DI], BL
INC SI INC DI LOOP LP1
MOV N, AL MOV AH, 4CH
INT 21H
CODE ENDS
END START
(2)在 FIRST 开始的一片连续的数据区中存放着 100 个数据,编写一个程序,统计第 1
个数据‘0’之前的数据个数。 程序流程图略。 参考源程序:
DATA SEGMENT
FIRST DB 10H,24H,34H, 73H,20H,44H,03H,36H,41H ;任取 9 个数做演示
COUNT EQU $-FIRST NUM DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA START: MOV AX,DATA
MOV DS,AX
MOV DL, 0 ;计数值初始为 0
MOV CX,COUNT
MOV BX, OFFSET FIRST
LP1: MOV AL, [BX] ;每次取一个数,与 0 比较
CMP AL, 00H JNE NEXT
JMP EXIT ;找到 0 则退出
NEXT: INC DL ;没找到 0 则计数值加 1
INC BX LOOP LP1
EXIT: MOV NUM, DL MOV AH, 4CH INT 21H
CODE ENDS
END START
实验四:子程序设计实验
将BUF开始的10个单元中两位十六进制数转换成ASCII码,并在屏幕上显示出来。要求码型 转换通过子程序HEXASC实现,参数传送采用寄存器传送方式。
程序流程图略。 参考源程序: (1)实现方法一:远过程调用 DATA SEGMENT
BUF DB 10H,2FH,0D0H,0FEH,33H,0F0H,20H,10H,3DH,0A2H
COUNT EQU $-BUF ;定义任意长度的一段 BUF DATA ENDS
STACK1 SEGMENT STACK
DB 100 DUP(?) ;设置足够深度的栈区
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK1
START: MOV AX,DATA MOV DS,AX
MOV SI,OFFSET BUF MOV CX,COUNT
AGAIN: MOV AL,[SI] ;逐个取数
MOV BL,AL
SHR AL,4
AND AL,0FH ;先对高字节部分转换(寄存器 AL 传参)
CALL FAR PTR HEXASC ;调用子程序
MOV DL,AL
MOV AH,02H ;显示高字节部分对应的字符
INT 21H
MOV AL,BL
AND AL,0FH ;再对低字节部分转换(寄存器 AL 传参)
CALL FAR PTR HEXASC ;调用子程序
MOV DL,AL
MOV AH,02H ;显示低字节部分对应的字符
INT 21H
MOV DL,20H
MOV AH,02H ;显示空格
INT 21H
INC SI
LOOP AGAIN
MOV AH,4CH INT 21H
CODE ENDS
CODEB SEGMENT ASSUME CS:CODEB
HEXASC PROC FAR
CMP AL,09H ;判断是不是数字
JA HEXATOF ;是字母则转到 HEXATOF
ADD AL,30H ;是数字则对应到数字的 ASCII 码
JMP ENDHEX
HEXATOF:ADD AL,37H ;是字母则对应到字母的 ASCII 码
ENDHEX: RET HEXASC ENDP CODEB ENDS
END START
(2)实现方法二:近过程调用
DATA SEGMENT
BUF DB 10H,2FH,0D0H,0FEH,33H,0F0H,20H,10H,3DH,0A2H
COUNT EQU $-BUF ;定义任意长度的一段 BUF DATA ENDS
STACK1 SEGMENT STACK
DB 100 DUP(?) ;设置足够深度的栈区
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK1
START: MOV AX,DATA MOV DS,AX
MOV SI,OFFSET BUF MOV CX,COUNT
AGAIN: MOV AL,[SI] ;逐个取数
MOV BL,AL
SHR AL,4
AND AL,0FH ;先对高字节部分做转换
CALL HEXASC
MOV DL,AL ;显示高字节部分对应的字符
MOV AH,02H INT 21H
MOV AL,BL
AND AL,0FH ;再对低字节部分做转换
CALL HEXASC
MOV DL,AL ;显示低字节部分对应的字符
MOV AH,02H INT 21H
MOV DL,20H ;显示空格
MOV AH,02H INT 21H
INC SI ;继续循环或退出
LOOP AGAIN
MOV AH,4CH INT 21H
HEXASC PROC NEAR CMP AL,09H
JA HEXATOF ADD AL,30H JMP ENDHEX
HEXATOF:ADD AL,37H ENDHEX: RET
HEXASC ENDP
CODE ENDS
END START
实验五:DOS 中断调用实验
(1)如果从键盘上依次输入的是一个数字和一个字母,则输出“RIGHT”标记后结束程序, 否则输出标记“ERROR”后转向原出错处重做。试编程实现该功能。
程序流程图略。 参考源程序:
DATA SEGMENT
MSG DB 0AH,0DH,RIGHT,0AH,0DH,$ WRN DB 0AH,0DH,ERROR,0AH,0DH,$
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA START: MOV AX,DATA
MOV DS,AX
AGAIN: MOV AH,01H ;等待用户输入 1 个字符并显示
INT 21H
CMP AL,39H JA EMSG CMP AL,30H
JB EMSG ;判断输入是否是数字,不是则报错
MOV AH,01H ;等待用户输入 1 个字符并显示
INT 21H CMP AL,A JB EMSG
CMP AL,Z ;判断输入是否是大写字母,不是则继续
JB EXIT ;判断是不是小写字母
CMP AL,a JB EMSG CMP AL,z
JB EXIT ;不是字母则报错,是字母则转到 EXIT
EMSG: LEA DX,WRN MOV AH,09H INT 21H
JMP AGAIN
EXIT: MOV DX,OFFSET MSG
MOV AH,09H ;显示“RIGHT”并退出
INT 21H
MOV AH,4CH
INT 21H CODE ENDS
END START
(2)编写一程序分类统计字符个数:即接收键入的一串字符(字符个数不超过50个,该字 符串用回车作为结束),并按数字、字母和其它字符分类计数,然后将结果存入digit、letter 和other 3个存储单元中,并显示结果。
程序流程图略。 参考源程序:
DATA SEGMENT
MSG1 DB 0AH, 0DH, Number of digit:,20H,$ MSG2 DB 0AH, 0DH, Number of letters:, 20H,$
MSG3 DB 0AH, 0DH, Number of other characters:, 20H, $ BUF DB 50
DB 0
DB 50 DUP(?) ;设置足够深的栈区
DIGIT DB ? LETTER DB ? OTHER DB ?
DATA ENDS
STACK1 SEGMENT STACK DB 100 DUP(?)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK1
START: MOV AX,DATA MOV DS,AX
MOV AH,0AH ;等待用户输入字符串并显示
MOV DX,OFFSET BUF INT 21H
MOV SI, OFFSET BUF MOV CL,[SI+1]
MOV CH,00H MOV AL,00H MOV AH,00H MOV BH,00H
AGAIN: MOV BL,[SI+2] CMP BL,30H
JB OTH ;ASCII 码小于 30H 则归类为“其它”
CMP BL,3AH
JB DIG ;ASCII 码大于等于 30H 小于 3AH 则归类为“数字” CMP BL,41H
JB OTH ;ASCII 码大于等于 3AH 小于 41H 则归类为“其它” CMP BL,5BH
JB LET ;ASCII 码大于等于 41H 小于 5BH 则归类为“字母” CMP BL,61H
JB OTH ;ASCII 码大于等于 5BH 小于 61H 则归类为“其它” CMP BL,7BH
JB LET ;ASCII 码大于等于 61H 小于 7BH 则归类为“字母”
OTH:
INC AL
;“其它”计数器加 1
DIG:
JMP ENDLP INC AH
;“数字”计数器加 1
LET:
JMP ENDLP INC BH
;“字母”计数器加 1
ENDLP: INC SI
LOOP AGAIN ;继续循环
MOV LETTER, BH MOV OTHER, AL
MOV DX, OFFSET MSG1
MOV AH,09H INT 21H
MOV AL, DIGIT CALL DISP
;显示“数字”有多少个
MOV DX, OFFSET MSG2
MOV AH,09H INT 21H
MOV AL, LETTER CALL DISP
;显示“字母”有多少个
MOV DX, OFFSET MSG3
MOV AH,09H INT 21H
MOV AL, OTHER CALL DISP
;显示“其它”有多少个
MOV AH,4CH INT 21H
DISP
PROC NEAR
;显示子程序
MOV DIGIT, AH ;统计各类个数
MOV AH,00H MOV DH,0AH DIV DH
MOV CH,AH ADD AL, 30H MOV DL, AL MOV AH, 02H INT 21H
ADD CH,30H MOV DL, CH MOV AH, 02H INT 21H
RET DISP ENDP
CODE ENDS
END START
实验六:扩展定时器/计数器接口实验
(1)计数器0工作于方式3,编写初始化程序,观察其输出OUT0信号的波形。修改计数初 值,观察OUT0信号的变化情况。 硬件连接方法:8254计数器0的CLK0端接规则的脉冲输入(频率自选),OUT0接示波器的 正极;示波器负极接地。
程序流程图略。 参考源程序:
DATA SEGMENT
DB 100 DUP(?) DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA START: MOV AX,DATA
MOV DS,AX
MOV DX,20FH ;写入计数器0的控制字
MOV AL,00010110B OUT DX,AL
MOV DX,20CH ;写入计数器0的计数初值
MOV AL,05H OUT DX,AL
MOV AH,4CH INT 21H
CODE ENDS
END START
(2)将计数器1和计数器0级联起来,二者均工作于方式3,编写初始化程序,观察OUT1 和OUT0信号的波形,说明二者的关系。修改计数初值,观察OUT0和OUT1输出波形的变 化情况。 硬件连接方法:8254计数器1的CLK1端接规则的脉冲输入(频率自选),OUT1接8254计数 器0的CLK0,计数器0的输出OUT0接示波器正极;示波器负极接地。
程序流程图略。 参考源程序:
DATA SEGMENT DB 100 DUP(?)
DATA ENDS CODE SEGMENT
ASSUME CS:CODE,DS:DATA START: MOV AX,DATA
MOV DS,AX
MOV DX,20FH
MOV AL,00010110B ;写入计数器0的控制字
OUT DX,AL
MOV DX,20CH ;写入计数器0的计数初值
MOV AL,05H OUT DX,AL
MOV DX,20FH
MOV AL,01010110B ;写入计数器1的控制字
OUT DX,AL
MOV DX,20DH ;写入计数器1的计数初值
MOV AL,02H OUT DX,AL
MOV AH,4CH INT 21H
CODE ENDS
END START
实验七:并行输入/输出接口 8255A 简单编程实验
(1)利用 8255A 的 B 口输出控制两组发光二级管 L1,L3,L5,L7 和 L2,L4,L6,L8 亮灭交替变 化。
分析:
按照题目要求,当 8255A 的 B 口输出为 01010101B(55H)时,发光二极管 L1,L3,L5,L7 会被点亮,当 8255A 的 B 口输出为 10101010B (0AAH)时,发光二极管 L2,L4,L6,L8 会被点 亮。因此,通过延时改变 8255A 的 B 口输出,即可实现两组发光二极管的亮灭交替变化。 由于 LED 随时出于准备好的状态,因此 8255A 的 B 口可工作于方式 0 输出,其它端口未使 用,无需考虑。因此,8255A 的方式控制字为:10000000B(80H)。
硬件连接方法:
8255A 的 B 口 PB0~PB7 分别连接 L1~L8。 程序流程图略。
参考源程序:
.486
DATA SEGMENT
PORTA DW 208H ;8255A端口A地址 PORTB DW 209H ;8255A端口B地址 PORTC DW 20AH ;8255A端口C地址 PORT_CTR DW 20BH ;8255A控制端口地址
DATA ENDS
STACK1 SEGMENT STACK DB 100 DUP(?)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK1
START: MOV AX,DATA MOV DS,AX
MOV DX, PORT_CTR MOV AL, 10000000B
;8255A初始化
;控制字
OUT DX, AL
MOV DX, PORTB MOV AL, 00H OUT DX, AL
;8255A端口B清零,LED初始化(全灭)
LP0:
MOV BL, 01010101B MOV AL, BL
OUT DX, AL CALL DELAY
NOT AL
MOV BL, AL
MOV AH, 01H ;调用BIOS的16H功能判断键盘是否有输入
INT 16H JNZ EXIT JMP LP0
EXIT: MOV AH, 4CH INT 21H
DELAY PROC NEAR ;延时子程序(可通过修改NOP指令数量改变延时时间) MOV ECX, 0FFFFFFFH
LP2: NOP
LOOPD LP2
RET DELAY ENDP
CODE ENDS
END START
(2)利用 8255A 的 A 口读入 8 个开关 K1~K8 的状态,当只有 K1 合上时,L1~L8 显示
00000001B;当只有 K1 和 K2 合上时,L1~L8 显示 00000010B;当只有 K1,K2 和 K3 合上 时,L1~L8 显示 00000011B;当只有 K1,K2,K3 和 K4 合上时,L1~L8 显示 00000100B;… 直到所有开关合上时,L1~L8 显示 00001000B,并结束程序的运行。发光二极管的状态通 过 8255A 的 B 口进行控制。
分析:
按照题目要求,可以通过查询的方式读取 8255A 的 B 口状态,并根据查询的结果给 A 口送出相应数据,A 口工作在方式 0 的输入状态,B 口工作在方式 0 输出状态,C 口不需要 考虑,所以 8255A 的方式控制字为:10010000B)
硬件连接方法:
(1)8255A 的 A 口 PA0~PA7 对应连接 K1~K8;
(2)8255A 的 B 口 PB0~PB7 对应连接 L1~L8; 源代码:
DATA SEGMENT
LIST DB 01H, 03H, 07H, 0FH, 1FH, 3FH, 7FH, 0FFH DATA ENDS
STACK1 SEGMENT STACK DB 100 DUP(?)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK1
START: MOV AX, DATA
MOV DS, AX
MOV DX, 20BH ;8255A初始化
MOV AL, 10010000B OUT DX, AL
MOV DX, 209H ;8255A的B口清零,LED初始化(全灭) MOV AL, 00H
OUT DX, AL
L0: MOV DX, 208H ;读8255A的A口,获得开关状态
IN AL, DX
MOV BL, 00H MOV CX, 8
MOV SI, OFFSET LIST L1: INC BL
CMP AL, [SI] JZ FIND INC SI
LOOP L1
JMP L0
FIND:
MOV AL, BL MOV DX, 209H
;当前开关状态为表中所列状态之一
;显示LED状态
OUT DX, AL CMP AL, 08H JNZ L0
MOV AH, 4CH INT 21H
CODE ENDS
END START
实验八:并行输入/输出接口 8255A 综合应用实验
(1)利用8254计数器0、计数器1和8255A的B口实现对发光二极管的定时控制,让8个发光 二极管每隔1s从左到右依次点亮。(要求计数器1的时钟脉冲频率为250kHz)。
分析: 根据题目要求,需要利用8254进行定时1s控制,定时到后,改变8255A的B口输出。可
以利用中断的方式实现,8254定时到时向CPU申请中断,CPU相应中断后在中断程序中改变
8255A的B口输出。 由于题目要求8254的输入脉冲频率为250kHz,所以需要级联计数器1和计数器0实现1s
定时(参考程序中利用计数器1进行20ms定时,计数器0进行50次计数,计数次数到时由OUT0 向CPU申请中断)。8255A的B口控制LED,可工作在方式0输出,A口未使用,为了选通实 验板上的中断输入C口的PC7须输出低电平,因此C口的高四位工作在方式0输出。综合上述 要求,8254和8255A的初始化参数为:
8254计数器1的计数初值为:N=20ms/4s=5000D;方式控制字为:01110100B (74H)
8254计数器0的计数初值为:N=50D;方式控制字为:00010100B (14H)
8255A的方式控制字:10000000B (80H);C口按位置位/复位控制字:00001110B (0EH)(使PC7复位,允许8254的OUT0中断到达系统8259的IRQ3端)
此外,利用中断方式实现题目要求的功能还需要设置系统8259芯片的中断屏蔽字和系统 存储器中的中断向量表(修改中断类型号为0BH的中断向量)。
硬件连接方法:
(1)250kHz脉冲输出接8254的CLK1,OUT1接CLK0,OUT0接IRQ;
(2)8255A的B口PB0~PB7对应连接L1~L8。
DATA
SEGMENT
PORT0 DW 20CH
;8254计数器0端口地址
PORT1 DW 20DH
;8254计数器1端口地址
PORT2 DW 20EH
;8254计数器2端口地址
PORT3 DW 20FH
;8254控制寄存器端口地址
PORTA DW 208H
;8255A的A口端口地址
PORTB DW 209H
;8255A的B口端口地址
PORTC DW 20AH
;8255A的C口端口地址
DATA
PORT_CTR DW 20BH ENDS
;8255A的控制寄存器端口地址
程序流程图略。 参考源程序:
STACK1 SEGMENT STACK DB 100 DUP(0)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, ES:DATA, SS:STACK1
START: MOV AX, DATA MOV DS, AX MOV ES, AX
MOV AL, 80H ; 8255初始化, B口方式0输出,C口高4位输出
MOV DX, PORT_CTR OUT DX, AL
MOV AL, 0EH ;PC7清零,允许8254中断到IRQ3
OUT DX, AL
MOV AL, 00H ;发光二极管初始化(全灭) MOV DX, PORTB
OUT DX, AL
MOV AX, 350BH ;保存系统原有0BH号中断的中断向量至堆栈
INT 21H PUSH ES PUSH BX
MOV AX, SEG INTPROC MOV DS, AX
MOV DX, OFFSET INTPROC
MOV AX, 250BH ;将程序要求的中断向量写入
INT 21H
IN AL, 21H ;设置8259的IMR寄存器,允许IRQ3中断
AND AL, 0F7H OUT 21H, AL
STI ;开中断,CPU可以响应外部可屏蔽中断
MOV DX, PORT3 ;8254计数器0初始化
MOV AL, 14H OUT DX, AL
MOV DX, PORT0 ;计数器0写入计数初值50D
MOV AL, 50D OUT DX, AL
MOV DX, PORT3 ;8254计数器1初始化
MOV AL, 74H OUT DX, AL
MOV DX, PORT1 ;计数器1写入计数初值5000D
MOV AX, 5000D OUT DX, AL MOV AL, AH OUT DX, AL
MOV BH, 80H ;BH存放当前8255A的B口输出
MOV AL, BH
MOV DX, PORTB ;8255A的B口输出
OUT DX, AL
WAIT0: NOP NOP NOP
MOV AH, 01H ;判断键盘上是否有键按下,若有则结束程序
INT 16H JNZ EXIT JMP WAIT0
EXIT: POP DX ;恢复中断向量表中的原有0BH号中断向量
POP DS
MOV AX, 250BH INT 21H
MOV AH, 4CH INT 21H
INTPROC PROC NEAR MOV AL, BH ROR AL,1
MOV BH, AL
MOV DX, PORTB ;向8255A的B口写出数据,点亮对应LED OUT DX, AL
MOV AL, 20H ;向8259发出中断结束命令
OUT 20H, AL IRET
INTPROC ENDP CODE ENDS
END START
(2)8255A的A口与8个开关相连,工作于方式1下,要求:利用当前的开关状态通过B口控 制L1~L8的亮或灭。A口的/STBA选通信号由按键K发出,每按一次K键,读入当前开关状态。 分析:
8255A的B口用来控制LED的亮灭,可工作在方式0下。 根据题意,可以通过查询方式不断读取8255A的C口状态确定K键是否按下,也可以利
用中断方式,当K键按下时,由INTRA(PC3)向CPU申请中断。当判断K键按下后,读取
8255A的A口状态,并通过B口显示到LED上。利用查询方式实现时,仅需要给定方式选择 控制字;利用中断方式实现时,除控制字外还需设定INTEA为1,允许INTRA申请中断。
因此,8255A的方式控制字为:10110000B(0B0H);使 INTEA(PC4)置1,其控制字为
00001001B(09H)。{注意:利用中断方式实现时还需要置PC7为0,使INTRA能到达8259
的IRQ3}
硬件连接与参考源程序:
(1)利用查询方式实现 硬件连接:
1)8255A的A口PA0~PA7与K1~K8对应相连;
2)8255A的B口PB0~PB7与L1~L8对应相连;
3)按键K接8255A的C口PC4。 参考源程序:
CODE SEGMENT ASSUME CS:CODE
START: MOV AL, 0B0H ; 8255A初始化,方式控制字10110000B
MOV DX, 20BH OUT DX, AL
MOV DX, 209H ;LED初始化
MOV AL, 00H OUT DX, AL
AGAIN: MOV AH, 01H ;判断计算机键盘上是否有键按下,若有结束程序
INT 16H JNZ EXIT
MOV DX, 20AH ;读入8255A的C口状态
IN AL, DX
TEST AL, 00010000B ;判断PC4=1?(K键是否按下) JNZ AGAIN
MOV DX, 208H ;读入8255A的A口状态
IN AL, DX
MOV DX, 209H ;将A口状态送8255A的B口
OUT DX, AL JMP AGAIN
EXIT: MOV AH, 4CH INT 21H
CODE ENDS
END START
(2)利用中断方式实现 硬件连接:
1)8255A的A口PA0~PA7与K1~K8对应相连;
2)8255A的B口PB0~PB7与L1~L8对应相连;
3)按键K接8255A的C口PC4;
4)8255A的C口PC3(INTRA)接IRQ。 参考源程序:
DATA
SEGMENT
PORTA DW 208H
; 8255A的A口地址
PORTB DW 209H
; 8255A的B口地址
PORTC DW 20AH
; 8255A的C口地址
DATA
PORT_CTR DW 20BH ENDS
; 8255A的控制口地址
STACK1 SEGMENT STACK
DB 100 DUP(0) STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, ES:DATA, SS:STACK1
START: MOV AX, DATA MOV DS, AX MOV ES, AX
MOV DX, PORT_CTR ;写入8255A方式控制字0B0H MOV AL, 0B0H
OUT DX, AL
MOV AL, 09H ;写入C口按位置位控制字,PC4置“1”
OUT DX, AL
MOV AL, 0EH ;写入C口按位复位控制字,PC7置“0”,开IRQ OUT DX, AL
MOV AX, 350BH ;保存系统原有中断号为0BH的中断向量到堆栈
INT 21H PUSH ES PUSH BX
MOV AX, SEG INTPROC ;向0BH号中断写入新的中断向量
MOV DS, AX
MOV DX, OFFSET INTPROC MOV AX, 250BH
INT 21H
IN AL, 21H ;允许8259的IRQ3中断
AND AL, 0F7H OUT 21H, AL
STI ;允许CPU响应可屏蔽中断
WAIT0: MOV AH, 01H ;判断是否有键按下,若有则结束程序,若无则等待
INT 16H JZ WAIT0
POP DX ;恢复系统中断向量表
POP DS
MOV AX, 250BH INT 21H
MOV AH, 4CH INT 21H
INTPROC PROC NEAR
MOV DX, PORTA ;读入8255A端口A的状态(开关
展开阅读全文