INCLUDE MACROS
LIB SEGMENT 'Code'
ASSUME CS:LIB
PUBLIC PRINT_HEX
PUBLIC PRINT_HEX4
PUBLIC HEX_KEYB
PUBLIC DEC_KEYB
PUBLIC READ_HEX4
PUBLIC READ_DEC4
PUBLIC PRINT_DEC
PUBLIC PRINT_OCT
PUBLIC PRINT_SIGNDEC
PUBLIC READSTR
PUBLIC STRLEN
PUBLIC READ_KEY
PUBLIC ECHO
;Ρουτίνα για την εκτύπωση δεκαεξαδικού ψηφίου
;Είσοδος| DL: ψηφίο προς εκτύπωση
PRINT_HEX PROC FAR
PUSH AX
PUSH DX
CMP DL, 9 ;Αν ο αριθµός είναι µεταξύ 0 και 9
JG ADDR1 ; προστίθεται
ADD DL,30H ; η τιµή 30H (’0’=30H).
JMP ADDR2
ADDR1:
ADD DL, 37H ;Διαφορετικά προστίθεται η τιµή 37H (’A’=41H).
ADDR2:
PRINT DL ;Τύπωσε το χαρακτήρα στην οθόνη
POP DX
POP AX
RET
PRINT_HEX ENDP
;Ρουτίνα για την εκτύπωση δεκαεξαδικού αριθμού 4-ψηφίων
;Είσοδος| DX: δεκαεξαδικός αριθμός 4-ψηφίων
PRINT_HEX4 PROC FAR
PUSH CX
PUSH BX
PUSH AX
PUSHF
MOV CX,4
MOV BX,DX
ADDR5:
ROL BX,1
ROL BX,1
ROL BX,1
ROL BX,1
MOV DX,BX
AND DL,0FH
CALL PRINT_HEX
LOOP ADDR5
POPF
POP AX
POP BX
POP CX
RET
PRINT_HEX4 ENDP
;Ρουτίνα για την εκτύπωση 16-bit αριθμού σε οκταδική μορφή
;Είσοδος| DX: 16-bit αριθμός
PRINT_OCT PROC FAR
PUSH AX
PUSH BX
PUSH CX
ROL DX,1 ; τυπώνω πρώτα το MSB
MOV BX,0
ADC BX,30H
PUSH DX
PRINT BL
POP DX
; ακολούθως συνεχίζω με τα υπόλοιπα 15-bits
; πέρνωντας τα ως 3-αδες
MOV CX,5
ADDR10:
ROL DX,1
ROL DX,1
ROL DX,1
MOV BX,DX
AND BX,0007H ; απομονώνω τα 3 λιγότερο σημαντικά bits
ADD BX,30H ; μετατρέπω τον αριθμό στον αντίστοιχο κωδικό
PUSH DX
PRINT BL ; ASCII και τον τυπώνω
POP DX
LOOP ADDR10
POP CX
POP BX
POP AX
RET
PRINT_OCT ENDP
;Ρουτίνα για την εκτύπωση 16-bit απρόσημου αριθμού σε δεκαδική μορφή
;Είσοδος| DX: 16-bit αριθμός
PRINT_DEC PROC FAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX,DX
MOV CX,0
ADDR8:
MOV DX,0
MOV BX,10 ; διαιρώ με το 10 τον αριθμό
DIV BX
INC CX ; αυξάνω το μετρητή των ψηφίων
PUSH DX ; το υπόλοιπο το αποθηκεύω στη στοίβα
CMP AX,0 ; ελέγχω αν το πηλίκο είναι 0
JNE ADDR8 ; αν είναι μηδέν τέλειωσα
ADDR9:
POP DX
ADD DX,30H ; μετατροπή του αριθμού στον αντίστοιχο
; ASCII
PRINT DL
LOOP ADDR9 ; επανέλαβε τη διαδικασία μέχρι να
; τελειώσουν οι αριθμοί
POP DX
POP CX
POP BX
POP AX
RET
PRINT_DEC ENDP
;Ρουτίνα για την εκτύπωση 16-bit προσημασμένου αριθμού σε δεκαδική μορφή
;Είσοδος| DX: 16-bit αριθμός,
;πχ αν κανουμε SUB DX,08H και ο DX ειναι 5 τοτε θα τυπωσει -3 ενω η PRINT_DEC 3
;Ένω η PRINT_DEC θα τυπωσει 253
PRINT_SIGNDEC PROC FAR
PUSH AX
PUSH BX
PUSH CX
MOV AX,DX
MOV CX,0
CMP DX,0
JGE ADDR12 ; ελέγχω αν ο αριθμός είναι θετικός
NEG DX ; αν δεν είναι τον μετατρέπω σε θετικό
NEG AX
PUSH AX
PRINT '-' ; και τυπώνω το -
POP AX
ADDR12:
MOV DX,0
MOV BX,10 ; διαιρώ με το 10 τον αριθμό
DIV BX
INC CX ; αυξάνω το μετρητή των ψηφίων
PUSH DX ; το υπόλοιπο το αποθηκεύω στη στοίβα
CMP AX,0 ; ελέγχω αν το πηλίκο είναι 0
JNE ADDR12 ; αν είναι μηδέν τέλειωσα
ADDR13:
POP DX
ADD DX,30H ; μετατροπή του αριθμού στον αντίστοιχο
; ASCII
PRINT DL
LOOP ADDR13 ; επανέλαβε τη διαδικασία μέχρι να
; τελειώσουν οι αριθμοί
POP CX
POP BX
POP AX
RET
PRINT_SIGNDEC ENDP
;Η υπορουτίνα διαβάζει ένα ΗΕΧ ψηφίο από το
;πληκτρολόγιο και το επιστρέφει σαν δυαδικό µέσω του AL, αν πατηθει Q τον επιστρεφει στον AL
HEX_KEYB PROC FAR
PUSH DX ;Επηρεάζετε από τη macro PRINT
IGNORE: READ ;Διάβασε τον χαρακτήρα από το πληκτρολόγιο
CMP AL,'Q' ;Αν είναι ο χαρακτήρας ’Q’ τέλος υπορουτίνας
JE ADDR4
CMP AL, 30H ;Εξέτασε αν ο χαρακτήρας είναι ψηφίο
JL IGNORE ;Αν όχι αγνόησέ τον και διάβασε άλλον
CMP AL,39H
JG ADDR3
PUSH AX
PRINT AL ;Τύπωσε το ψηφίο
POP AX
SUB AL,30H ;Μετέτρεψε το ψηφίο σε δυαδικό αριθµό (’0’=30)
JMP ADDR4
ADDR3: CMP AL,'A'
JL IGNORE
CMP AL,'F'
JG IGNORE
PUSH AX
PRINT AL
POP AX
SUB AL,37H ;Μετάτρεψε το ψηφίο σε δυαδικό αριθµό (’A’=41, 41H-
;31H=10H)
ADDR4: POP DX
RET
HEX_KEYB ENDP
;Ρουτίνα για την είσοδο δεκαδικού ψηφίου από το πληκτρολόγιο
;Έξοδος| AL: δεκαδικό ψηφίο σε διαδικη μορφη
DEC_KEYB PROC FAR
PUSH DX
IGNORE_DEC_KEYB:
READ
CMP AL, 'Q'
JE ADDR16
CMP AL, 30H
JL IGNORE_DEC_KEYB
CMP AL, 39H
JG IGNORE_DEC_KEYB
PUSH AX
PRINT AL
POP AX
SUB AL, 30H
ADDR16: POP DX
RET
DEC_KEYB ENDP
;Ρουτίνα για την είσοδο δεκαεξαδικού αριθμού 4-ψηφίων από το πληκτρολόγιο
;Έξοδος| DX: δεκαεξαδικός αριθμός 4-ψηφίων
READ_HEX4 PROC FAR
PUSH CX
MOV DX,0
MOV CX,4
ADDR6:
CALL HEX_KEYB
CMP AL,'Q'
JE QUIT_READ_HEX4
SHL DX,1
SHL DX,1
SHL DX,1
SHL DX,1
ADD DL,AL
LOOP ADDR6
QUIT_READ_HEX4:
POP CX
RET
READ_HEX4 ENDP
;Ρουτίνα για την είσοδο δεκαδικού αριθμού 4-ψηφίων από το πληκτρολόγιο, διαβαζει ακριβως 4 ψηφια
;Έξοδος| DX: δεκαδικός αριθμός 4-ψηφίων,
;αν βρει Q τοτε τερματιζεται και επιστρεφει το Q στον AL
READ_DEC4 PROC FAR
PUSH AX
PUSH CX
MOV DX,0
MOV CX,4
ADDR15: ; 4 επαναληψεις
MOV AX,10
MUL DX
MOV DX,AX
CALL DEC_KEYB
CMP AL,'Q'
JE QUIT_READ_DEC4
MOV AH,0
ADD DX,AX
LOOP ADDR15
QUIT_READ_DEC4:
POP CX
POP AX
RET
READ_DEC4 ENDP
;Ρουτίνα για την είσοδο συμβολοσειράσ από το πληκτρολόγιο
;Δέχεται στον ΒΧ το offset της συμβολοσειράς και την αποθηκεύει ξεκινώντας από το σημείο αυτό
;τερματιζει μολις βρει enter
READSTR PROC FAR
PUSH CX
PUSH DX
PUSH AX
PUSHF
MOV DI,00H
READ_STRING:
READ
CMP AL,0DH
JE END_STRING
PRINT AL
MOV [BX+DI],AL
INC DI
JMP READ_STRING
END_STRING:
MOV BYTE PTR[BX+DI],'$'
POPF
POP AX
POP DX
POP CX
RET
READSTR ENDP
;Ρουτίνα για την εύρεση του μήκους της συμβολοσειράς και επιστρέφει στον ΒΧ το μήκος της
;Δέχεται στον ΒΧ το offset της συμβολοσειράς
;Note: Η συμβολοσειρά θα πρέπει να τερματίζεται με το $
STRLEN PROC FAR
PUSH CX
PUSHF
MOV CX,00H
LOOP1:
CMP BYTE PTR [BX],'$'
JE EXIT_LOOP1
INC CX
INC BX
JMP LOOP1
EXIT_LOOP1:
MOV BX,CX
POPF
POP CX
RET
STRLEN ENDP
;Ρουτίνα που διαβάζει ένα πλήκτρο από το πληκτρολόγιο και τον γυρίζει στον AL
READ_KEY PROC FAR
PUSH DX
READ_KEY1:
MOV AH,6
MOV DL,0FFH
INT 21H
JE READ_KEY1
POP DX
RET
READ_KEY ENDP
;Τυπώνει τον ASCII code που περιέχει ο AL στην οθόνη
ECHO PROC FAR
PUSH DX
MOV AH,6
MOV DL,AL
INT 21H
POP DX
RET
ECHO ENDP
LIB ENDS
END