可以循环计数
关机状态
8086汇编语言源程序如下:
DATA SEGMENT X DB ?,?,?,? ;存放数据的每一位 X1 DW ? ;存放第一个数据值 X2 DW ? ;存放第二个数据值 Y DW ? ;存放运算结果 S DB ? ;存放运算符号值 E DB ? ;按下等号键标记 CC DB ? ;存放运算数据位数 H DB 0 ;存放按键行号 L DB 0 ;存放按键列号 DISCODE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H ;段码表 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AL,90H ;设置为A口输入,B口输出,C口输出 OUT 46H,AL MOV DI,OFFSET X+3 ;DI指向X的高位 KKK: CALL KEY ;扫描按键 JMP KKK ;以下为按键扫描子程序,程序返回后,在变量H和L中存放当前按键的行列号 KEY PROC CHECK: CALL DISP ;等待按键按下的同时进行显示 MOV AL,0F0H ;所有行输出低电平 OUT 44H,AL IN AL,40H CMP AL,0FFH ;读列值 JZ CHECK ;若都为高电平则无键按下,等待 MOV CX,50 LOOP $ ;延时消抖 IN AL,DX ;重读列值 CMP AL,0FFH JZ CHECK ;无键按下一直等待 MOV H,0 ;有键按下,先把行列号变量清0 MOV L,0 MOV BL,01H MOV BH,0FEH ;扫描法读键值:从第一行开始测试,即PC0输出低电平 NEXT: MOV AL,BH OUT 44H,AL NEXTH: IN AL,40H ;读列值,判断是第几列有键按下 TEST AL,BL ;从第一列开始判断 JZ WAIT0 ROL BL,1 CMP BL,10H ;当前行状态下没有任何列有键按下,则转为对下一行的测试 JZ NEXTL INC H ;每判断一列,列号加1 JMP NEXTH ;再对下一列进行判断 NEXTL: MOV H,0 MOV BL,01H ROL BH,1 ;对下一行测试,让下一个PC口输出低电平 CMP BH,0EFH JZ EXIT INC L JMP NEXT WAIT0: IN AL,40H ;若有键按下,则等该按键松开后再计算键值 CMP AL,0FFH JNZ WAIT0 MOV CX,50 LOOP $ ;延时消抖 IN AL,40H CMP AL,0FFH JNZ WAIT0 CALL KEYVALUE ;调计算键值子程序 EXIT: RET KEY ENDP ;以下为计算键值子程序,通过行列号计算键值(键值=列号*4+行号) ;键值存放在DL寄存器中 KEYVALUE PROC MOV DL,L MOV DH,H SHL DL,1 SHL DL,1 ;列号乘4 ADD DL,DH CMP DL,9 ;按下的是数字键 JNG NUM_CALL CMP DL,14 JL CONT_CALL ;按下的是运算键 CMP DL,14 JZ OUTP_CALL ;按下的是等于键 CMP DL,15 JZ CLR_CALL ;按下的是清除键 NUM_CALL: CALL NUMBER ;调数字键处理子程序 JMP EXIT1 CONT_CALL: MOV S,DL ;存放运算键的键值 MOV E,0 CALL COUNT ;调运算键处理子程序,计算第一个加数 JMP EXIT1 OUTP_CALL: CALL OUTP ;调等号键处理子程序 JMP EXIT1 CLR_CALL: CALL CLEAR ;调清除键处理子程序 EXIT1: RET KEYVALUE ENDP ;以下为清除键处理子程序,按下清除键后,X变量全部清0 CLEAR PROC MOV X[3],0 MOV X[2],0 MOV X[1],0 MOV X[0],0 CALL BITP RET CLEAR ENDP ;以下为等号键处理子程序,该子程序负责将第二个运算数据的数值计算出来存入X2变量 ;并根据运算符号,调用相应的运算子程序 OUTP PROC PUSH AX PUSH DX PUSH BX INC E CALL COUNT ;调运算键处理子程序,计算第二个运算数据 CMP S,10 JZ ADD_CALL ;运算符为加号,则调用加法子程序 CMP S,11 JZ SUB_CALL ;运算符为减号,则调用减法子程序 CMP S,12 JZ MUL_CALL ;运算符为乘号,则调用乘法子程序 CMP S,13 CALL DIVP ;运算符为除号,则调用除法子程序 JMP STORE1 ADD_CALL: CALL ADDP JMP STORE1 SUB_CALL: CALL SUBP JMP STORE1 MUL_CALL: CALL MULP STORE1: MOV AX,Y ;以下程序将各运算子程序返回的运算结果,按位分解,送入X变量 MOV DX,0 MOV BX,1000 DIV BX MOV X[0], AL MOV AX,DX MOV BL,100 DIV BL MOV X[1],AL MOV AL,AH MOV AH,0 MOV BL,10 DIV BL MOV X[2],AL MOV X[3],AH POP BX POP DX POP AX RET OUTP ENDP ;以下为运算键处理子程序,该程序将第一个运算数据的数值计算出来并存入X1变量 ;或者将第二个运算数据的数值计算出来并存入X2变量 ;将运算符的值存入S变量 COUNT PROC PUSH AX PUSH BX PUSH DX MOV DX,0 CALL BITP ;测试X中的数据是多少位 CMP CC,4 ;输入的数据是4位数 ? JZ C4 CMP CC,3 ;输入的数据是3位数 ? JZ C3 CMP CC,2 ;输入的数据是2位数 ? JZ C2 JMP C1 ;输入的数据是1位数 ? C4: MOV AX,0 MOV AL,X[0] MOV BX,1000 MUL BX MOV DX,AX C3: MOV AL,X[1] MOV BL,100 MUL BL ADD DX,AX C2: MOV AL,X[2] MOV BL,10 MUL BL ADD DX,AX C1: MOV AL,X[3] MOV AH,0 ADD DX,AX CMP E,1 JNZ X1_S MOV X2,DX ;按下的是等号,则将第二个运算数据的值存入X2变量 JMP EXIT3 X1_S: MOV X1,DX ;按下的是运算符号,则将第一个运算数据的值存X1变量 MOV X[3],0 ;清空X变量 MOV X[2],0 MOV X[1],0 MOV X[0],0 EXIT3: POP DX POP BX POP AX RET COUNT ENDP ;以下为数字键处理子程序 ;该程序,将输入的数据按位存放在X变量中,并由CC记录数据的位数 NUMBER PROC CMP E,1 JNZ CONTINUE MOV E,0 CALL CLEAR CONTINUE: CMP CC,0 ;目前数据为0位,即没有数据,则转到SSS JZ SSS ;若已有数据,以下程序将X左移8位。 ;例如:先输入“1”,当再输入2时, ;先要将“1”从个位移到十位,然后再将“2”存放到个位 PUSH AX PUSH DX MOV AL,X[3] MOV AH,X[2] MOV DL,X[1] MOV DH,X[0] MOV CX,8 LL: SHL AX, 1 RCL DX,1 LOOP LL MOV X[3],AL MOV X[2],AH MOV X[1],DL MOV X[0],DH POP DX POP AX SSS: MOV [DI],DL ;将当前键入的数据存放到X的最低位 INC CC ;数据位数加1 CMP CC,4 ;判断数据位数 JNG EXIT2 MOV CC,0 ;如果数据超过4位,重新从最低位开始存放 MOV X[2],0 MOV X[1],0 MOV X[0],0 EXIT2: CALL DISP ;调显示子程序,显示输入的数据 RET NUMBER ENDP ;加法子程序 ADDP PROC PUSH AX MOV AX,X1 ADD AX,X2 MOV Y,AX POP AX RET ADDP ENDP ;减法子程序 SUBP PROC PUSH AX MOV AX,X1 SUB AX,X2 MOV Y,AX POP AX RET SUBP ENDP ;乘法子程序 MULP PROC PUSH AX PUSH DX MOV AX,X1 MOV DX,X2 MUL DX MOV Y,AX POP DX POP AX RET MULP ENDP ;除法子程序 DIVP PROC PUSH AX PUSH BX PUSH DX MOV DX,0 MOV AX,X1 MOV BX,X2 DIV BX MOV Y,AX POP DX POP BX POP AX RET DIVP ENDP ;显示子程序 ,将X中的数值按位显示出来 DISP PROC PUSH BX PUSH AX MOV BH,0 LEA SI,DISCODE CALL BITP ;测试X位数 CMP CC,4 JZ QIAN CMP CC,3 JZ BAI CMP CC,2 JZ SHI CMP CC,1 JMP G JMP NONE QIAN: MOV AH,11100000B ;从第4位开始显示 MOV AL,AH OUT 44H,AL MOV BL,X[0] MOV AL,[SI+BX] OUT 42H,AL CALL DELY MOV AL,0 OUT 42H,AL BAI: MOV AH,11010000B ;从第3位开始显示 MOV AL,AH OUT 44H,AL MOV BL,X[1] MOV AL,[SI+BX] OUT 42H,AL CALL DELY MOV AL,0 OUT 42H,AL SHI: MOV AH,10110000B ;从第2位开始显示 MOV AL,AH OUT 44H,AL MOV BL,X[2] MOV AL,[SI+BX] OUT 42H,AL CALL DELY MOV AL,0 OUT 42H,AL G: MOV AH,01110000B ;从第1位开始显示 MOV AL,AH OUT 44H,AL MOV BL,X[3] MOV AL,[SI+BX] OUT 42H,AL CALL DELY JMP EXIT4 …………………… …………限于本文篇幅 余下代码请下载附件…………
复制代码