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