仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (92.73 KB, 下載次數: 84)
下載附件
2022-4-30 16:13 上傳
cbb0ad71ca1bff8c430defb6e0d27adf.png (59.44 KB, 下載次數: 68)
下載附件
2022-4-30 11:32 上傳
3972e8a38d3f157711400b13be0ba473.png (10.08 KB, 下載次數: 61)
下載附件
2022-4-30 11:32 上傳
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
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼 代碼與Proteus仿真下載:
計算器8086.7z
(45.45 KB, 下載次數: 109)
2022-4-30 16:13 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|