MYDATA SEGMENTNUM DB 4 DUP(0)SUM DB 3 DUP(0)MYDATA ENDSSTACK SEGMENTDW 200 DUP(?)STACK ENDSMYCODE SEGMENTASSUME CS:MYCODE,DS:MYDATA,ES:MYDATA,SS:STACK0SOFTDLY PROCPUSH BXPUSH CXMOV BL,50DELAY:MOV CX,3800WAITA:LOOP WAITADEC BLJNZ DELAYPOP CXPOP BXRETSOFTDLY ENDPSAOMIAO PROCPUSH AXPUSH BXPUSH CXPUSH DXMOV DX,0600H ;设置8255的PA端口地址MOV AL,00H ;使行输出全为0OUT DX,ALLP1: MOV DX,0602H ; 设置8255 PB端口地址IN AL,DX ; 读入列线值AND AL,0FH ; 屏蔽高位无关位CMP AL,0FH ; 列线值是否全为1JZ LP1 ; 若列线值全为1,则无键按下,等待按键 MOV CX,2000H ; 设置循环次数DELAY1:LOOP DELAY1 ; 若有按键按下,延迟20MS,清除抖动 IN AL,DXAND AL,0FHCMP AL,0FHJZ LP1LP2:MOV BL,4 ; 行扫描次数送BLMOV BH,4 ; 列扫描次数送BHMOV AL,0FEH ; 设置行扫描初值MOV CH,0FFH ; 设置起始键号为FFHLP3:MOV DX,0600H ; 设置8255PA端口地址OUT DX,AL ; 输出扫描初值ROL AL,1 ; 修改扫描码,为扫描下一行做准备MOV AH,AL ; 保持修改后的扫描码MOV DX,0602H ; 设置8255PB端口地址IN AL,DX ; 读入列值AND AL,0FH ; 屏蔽高位无关位CMP AL,0FH ; 查列线是否全为1JNZ LP4 ; 有,则转去找该列线ADD CH,BH ; 无,则修改键号指向该行末列键号MOV AL,AH ; 取回扫描码DEC BL ; 行值减1JNZ LP3 ; 行末查完转下一行JMP LP2 ; 重新开始扫描键盘LP4:INC CH ;键号加1,指向本行首列键号RCR AL,1 ; 右移一位JC LP4MOV [SI],CH ;键号送入[SI]中INC SIPOP DXPOP CXPOP BXPOP AXRETSAOMIAO ENDPSTART:MOV AX,MYDATA ;主程序开始MOV DS,AXMOV ES,AXMOV SI,OFFSET NUMMOV DI,OFFSET SUMMOV DX,0606H ;8255控制口地址MOV AL,82H ;方式控制字,PA口方式0输入(行),PB口方式0输入(列) OUT DX,ALMOV CX ,2L1:CALL SAOMIAO ;输入第一个数CALL SOFTDLYLOOP L1MOV CX,2L2:CALL SAOMIAO ;输入第二个数CALL SOFTDLYLOOP L2MOV CX,2MOV SI,OFFSET NUMCLCL3:MOV AL,[SI+1] ;开始进行加法运算ADC AL,[SI+3]AAAMOV [DI+2],ALDEC DIDEC SILOOP L3MOV AH,0 ;防止溢出,保存进位ADC AH,0MOV [DI+2],AHMOV DI,OFFSET SUML4:MOV DX,0604H ;送8255的PC口地址MOV AH,[DI+1]ROL AH,4MOV AL,[DI+2]ADD AL,AHOUT DX,AL ;将十位,个位输出到PC口使LED灯显示 MOV AL,[DI]ROL AL,4MOV DX,0600HOUT DX,AL ;将百位输出到PA口高4位使LED灯显示 MOV CX,20L5:CALL SOFTDLY ;延迟2秒后清零LOOP L5MOV AX,0OUT DX,AXMOV DX,0604HOUT DX,AXJMP STARTMYCODE ENDSEND START。