單片機匯編案例之統計正負數個數


這是我單片機實驗作業的源碼,統計正負數個數。寫得不好,僅供參考。如有BUG,歡迎指正。

;;;;本程序從鍵盤獲取輸入,並統計輸入的正整數和負整數的個數,結果存於40H、41H;
;;;;此處把0歸於正數。數值范圍 -128 - 127
ORG 00H
LCALL GETKEY ;從鍵盤獲取數據,輸入的必須是十進制整數,可帶負號,每個整數之間必須有其他字符
LCALL Static ;統計正負數個數
SJMP $

;; 統計正負數個數
Static:
MOV R1, #30H ;數據地址指針
MOV 41H, #00H ;統計正數個數	   由於統計用地址單元與數據區單元很近,數據區最多存放16個數據
MOV 40H, #00H ;統計負數個數 
MOV 90H, R7
MOV R2, 90H	 ;R2存放數據個數

WHIL: ;取下一個數,判斷正負
MOV A, @R1
JB ACC.7, Nege 
INC 40H	 ;正數
SJMP IncR
Nege:
INC 41H	 ;負數
IncR:
INC R1
DJNZ R2, WHIL
RET

;;串口通信模式1初始化
initmod1: 
MOV TMOD, #20H ; 設置T1為模式2
MOV TL1, #0E8H ; 裝入定時常數, 波特率1200bit/s
MOV TH1, #0E8H ; 自動重裝
MOV SCON, #50H ;設置串行通信模式1 ,允許接收
SETB TR1 ; 啟動T1
RET

;;;獲取鍵盤輸入,數據暫存50H, 再轉換成數字存進30H
GETKEY:
LCALL String ;輸出提示字符串
LCALL Input	;獲取鍵盤輸入的字符串
LCALL Deci
RET


;提示字符串:Enter a group decimal integer:
MSG: DB 0x45,0x6e,0x74,0x65,0x72,0x20,0x61,0x20,0x67,0x72,0x6f,0x75,0x70,0x20,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x20,0x69,0x6e,0x74,0x65,0x67,0x65,0x72,0x3a,0x00

;;發送字符串
String:
LCALL initmod1 ;串口通信模式1初始化
MOV DPTR, #MSG ;取發送數據區首地址
Show:
CLR A 
MOVC A, @A+DPTR 
JZ Finish ;檢查字符是否為結束標志0H, A=0,則字符輸出完成
MOV SBUF, A ;在UART窗口顯示字符
CLR TI 
JNB TI, $ 
INC DPTR 
SJMP Show 
Finish:
CLR TR1 ;關閉定時器T1
RET

;;讀取鍵盤輸入字符串並存入以50H為首地址的單元
Input:
LCALL initmod1 ;串口通信模式1初始化
MOV R0, #50H ;設接收數據的地址指針為R0
Read: ;從UART窗口讀取數據並打印
CLR RI 
JNB RI, $ 
MOV A, SBUF 
CJNE A, #0DH, Continue ;檢查回車字符0DH, 不是回車繼續讀取
SJMP ReadOver ;回車字符,結束讀取
Continue: ;打印用戶輸入並保存
MOV SBUF, A ;打印接收到的數據
CLR TI
JNB TI, $
CJNE A, #08H, Store ;檢查退格字符\b, 不是退格,則保存數據
DEC R0 ;是退格,數據指針回退
SJMP Read
Store:
MOV @R0, A ;保存數據
INC R0 ;后移數據指針
SJMP Read ;循環讀取
ReadOver: ;讀取結束,在字符串后加上結束符0H
MOV @R0, #00H
CLR TR1 ;關閉定時器
RET

;;將首地址為50H的單元中的字符串轉化為十進制數,存30H, 個數存R7
;;可轉化的字符串格式:-12, 30, -45	  每個數之間必須有其他字符隔開 -12@34 也行 表示-12和34
Deci:
MOV R3, #30H ;R3指向存放十六進制數的地址
MOV R1, #90H ;R1指向存放中間結果的地址
MOV R2, #00H ;R2存放中間結果的位數
MOV R0, #50H ;R0指向數據源
MOV R7, #00H ;R7存放最后結果個數
SJMP Wh 
While:
INC R0 ;有些分支直接跳轉過來,R0還沒加1,只好這樣做了。
Wh:
MOV A, @R0
JNZ Trans 	  ;
SETB 0D1H	  ;A=0,為字符串結束標志, 標記結束
SJMP Derive	; 並跳轉,合成最后一個整數
Trans:
CLR C
SUBB A, #30H ;將字符轉化為數字
JC Neg ;C=1,A<30H。不是數字, 跳轉去判斷是否為負號
CJNE A, #0AH, C1 ;大於等於10,C=0
C1:JNC Derive ;大於等於10, C=0,不是數字,數字結束轉去合成
MOV @R1, A ;將轉化后的數字存進中間結果單元
INC R1 ;后移中間結果位置
INC R2 ;記錄中間結果位數
SJMP While
Neg:
MOV A, @R0
CLR C
SUBB A, #2DH
JNZ Derive		;不是負號,轉去合成
SETB F0			;標記為負數
SJMP While 
Derive: ;將中間結果合成為最后結果
CJNE R2, #00H, Deri		;判斷R2是否為0
JNB 0D1H, While			;判斷是否結束 0D1H != 1	繼續循環
SJMP Over				;0D1H = 1 結束
Deri:
MOV R1, #90H ;將R1重新指向開始位置
CLR A
Der:		 
MOV B, #0AH
MUL AB
ADD A, @R1
INC R1
DJNZ R2, Der
JNB F0, Stor  ;是正數,跳轉,直接保存
XRL A, #0FFH
INC A
CLR F0
Stor:
MOV 90H, A ;先把結果存進90H, 再存進30H
MOV A, R3 ;R3不能間址,只好借助其他寄存器
INC R3
INC R7
MOV R1, A
MOV @R1, 90H
MOV R1, #90H
JNB 0D1H, While	;結束標志位不為1,則繼續讀取字符串
Over:
RET

END


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM