You are on page 1of 160

ΠΑΝΕΠΙΣΤΗΜΙΟ ΔΥΤΙΚΗΣ ΑΤΤΙΚΗΣ

ΣΧΟΛΗ ΜΗΧΑΝΙΚΩΝ
ΤΜΗΜΑ ΗΛΕΚΤΡΟΛΟΓΩΝ & ΗΛΕΚΤΡΟΝΙΚΩΝ ΜΗΧΑΝΙΚΩΝ

Αρχιτεκτονική Υπολογιστικών Συστημάτων

Σημειώσεις Εργαστηριακού Μέρους

Αθήνας 2018
2

Απαραίτητο Θεωρητικό Υπόβαθρο:

Αρχιτεκτονική του 80x86


• Ο επεξεργαστής 8086
• Η κεντρική μνήμη και οι συσκευές Ι/Ο
• Η κεντρική μνήμη
• Διευθυνσιοδότηση Εισόδου/Εξόδου (Ι/Ο)
• Οι καταχωρητές του 8086
• Διευθυνσιοδότηση μνήμης
• Ο σωρός (stack)
• Διακοπές
• Διακοπές software
• Εξωτερικές διακοπές (hardware)

Περιεχόμενα

1. Διευθυνσιοδότηση μνήμης

2. Ο σωρός (stack)

3. Προγραμματισμός σε Assembly

3.1 Δημιουργία ενός προγράμματος


3.1.1 Αρχεία COM και ΕΧΕ

3.2 Οι ψευδοεντολές (directives) του assembler


3.2.1 Ψευδοεντολές ορισμού δεδομένων
3.2.2 Άλλα directives

3.3 Η δομή ενός προγράμματος


4.3.1 Χρήση μοντέλων
4.3.2 Μέθοδος αναλυτικού καθορισμού των segments
4.3.3 Υπορουτίνες (Procedures)
4.3.4 Μακροεντολές (macros)

3.4 Χρήση των ρουτινών του DOS και του BIOS

3.5 Κονσόλα – είσοδος /έξοδος χαρακτήρων


3

3.6 Απεικόνιση στην οθόνη

ΠΑΡΑΡΤΗΜΑ Α

ΠΑΡΑΡΤΗΜΑ Α: Η ΓΛΩΣΣΑ ASSEMBLY ΤΟΥ 8086

1 Κατηγορίες Εντολών

2 Εντολές μεταφοράς δεδομένων


2.1 Η εντολή MOV
2.2 Οι εντολές PUSH και ΡΟΡ
2.3 Οι εντολές LEA, LDS, LES
2.4 Οι εντολές εισόδου / εξόδου (ΙΝ και OUT)
2.5 Οι υπόλοιπες εντολές μεταφοράς δεδομένων

3 Αριθμητικές και λογικές εντολές

4 Εντολές ολίσθησης και περιστροφής

5 Εντολές χειρισμού αλφαριθμητικών (strings)


5.1 Οι εντολές επανάληψης
5.2 Εντολές μεταφοράς μπλοκ δεδομένων
5.3 Εντολές εύρεσης και σύγκρισης string

6 Εντολές χειρισμού των flags

7 Εντολές ελέγχου προγράμματος


7.1 Οι εντολές JMP
7.2 Οι εντολές LOOP
7.3 Οι εντολές CALL και RET
7.4 Εντολές διακοπών

8 Εντολές ελέγχου του επεξεργαστή

ΠΑΡΑΡΤΗΜΑ Β

Περιβάλλον Εξομοίωσης EMU8086

ΠΑΡΑΡΤΗΜΑ Γ

Σετ εντολών του 8086


4

ΠΑΡΑΡΤΗΜΑ Δ

Οι διακοπές του DOS και του BIOS

INT 5 - Print Screen

INT 9 - Keyboard Interrupt (Hardware Handler)

INT 10 - Video BIOS Services

INT 12 - Memory Size Determination

INT 14 - BIOS Asynchronous Communications Services

INT 16 - Keyboard BIOS Services

INT 21 - Συναρτήσεις DOS

INT 22 - Program Terminate

INT 33 - Mouse Function Calls


5

Θεωρητικό Υπόβαθρο

1 Διευθυνσιοδότηση μνήμης

Ο 8086 έχει 20 γραμμές διευθύνσεων, άρα μπορεί να προσπελάσει άμεσα μέχρι 220 =
1Μ θέσεων μνήμης (θυμίζουμε ότι 1Μ=1.048.576). Η χαμηλότερη θέση έχει
διεύθυνση 00000Η και η υψηλότερη FFFFFH. Η κάθε θέση μνήμης έχει
χωρητικότητα 1byte (8 bits).

Η άμεση προσπέλαση αυτών θα απαιτούσε όμως 20μπιτους καταχωρητές. Αντί αυτού


χρησιμοποιούμε την μέθοδο segment – offset. Η μνήμη χωρίζεται σε τμήματα (segments)
των 64 Κbytes το καθένα. Το κάθε segment μπορεί να ξεκινά σε οποιαδήποτε διεύθυνση της
μνήμης με τον μοναδικό περιορισμό η διεύθυνση αυτή να είναι πολλαπλάσιο του 16 (10Η).
Έτσι τα 4 δεξιότερα δυαδικά ψηφία (ή το δεξιότερο δεκαεξαδικό) της αρχικής διεύθυνσης
κάθε segment θα είναι πάντα 0. Με τον τρόπο αυτό αρκούν μόνο 16 bit (τα περισσότερο
σημαντικά) για να παρασταθεί η διεύθυνση αυτή, άρα ένας δεκαεξάμπιτος καταχωρητής
αρκεί. Για τον σκοπό αυτό χρησιμοποιούνται οι καταχωρητές segment. Από εκεί και έπειτα
μια οποιαδήποτε φυσική (20μπιτη) διεύθυνση μπορεί να παρασταθεί από το segment στο
οποίο ανήκει και την μετατόπιση (offset) μέσα σ΄αυτό. Η μετατόπιση αυτή μπορεί
πλέον να
παρασταθεί με έναν άλλο δεκαεξάμπιτο καταχωρητή (τον offset register), διότι 216 = 64Κ.

Παράδειγμα: Έστω ότι DS=1000H, AX=0540H. Σε ποια φυσική διεύθυνση αντιστοιχεί ο


συνδυασμός DS:AX;

Ο συμβολισμός DS:AX παριστάνει την φυσική (20μπιτη) διεύθυνση που προκύπτει αν σαν
αρχική διεύθυνση segment θεωρήσουμε το περιεχόμενο του καταχωρητή DS
πολλαπλασιάζοντάς το επί 16 (ή 10Η), έτσι ώστε να γίνει 20μπιτο και μετατόπιση μέσα στο
segment αυτό ίση με το περιεχόμενο του ΑΧ. Άρα ο γενικός κανόνας που ισχύει είναι:

(Φυσική Διεύθυνση) = segment * 10Η + offset

Στο παράδειγμά μας η φυσική διεύθυνση θα είναι 1000Η * 10Η + 0540Η = 10000Η +
0540Η = 10540Η.

Η αντιστοιχία αυτή είναι μονοσήμαντη, δηλαδή ο συνδυασμός segment:offset δίνει πάντα


μια συγκεκριμένη φυσική διεύθυνση. Το ανάποδο όμως δεν ισχύει, μια φυσική δηλαδή
διεύθυνση μπορεί να αποδοθεί σε πάρα πολλούς συνδυασμούς
segment:offset. Πίσω στο παράδειγμά μας, η ίδια φυσική διεύθυνση προκύπτει και από
6

τους συνδυασμούς 1050Η:0040Η, 1040Η:0140Η, 1054H:0000H κοκ.

Σε ορισμένες περιπτώσεις το offset μιας διεύθυνσης δίνεται έμμεσα π.χ. σαν


άθροισμα των καταχωρητών ΒΧ και SI. Το άθροισμα όμως δύο 16μπιτων αριθμών πιθανόν
να είναι 17μπιτος (να μένει κρατούμενο). Σε αυτή την περίπτωση ως offset θεωρούνται τα
16 λιγότερο σημαντικά bit (πρόσθεση modulo 16). Το γεγονός αυτό μας οδηγεί στο
συμπέρασμα ότι κάθε segment είναι κυκλικό δηλαδή ότι αν αυξάνουμε τον
καταχωρητή offset συνεχώς πηγαίνουμε χαμηλότερα σε μεγαλύτερες διευθύνσεις, όταν όμως
φτάσουμε στο τέλος του segment δηλ. σε offset FFFFH, τότε αυξάνοντας κατά ακόμη μία
μονάδα πάμε σε offset 0000H, δηλ. ξανά στην αρχή του! Έτσι ότι και να κάνουμε με τον
offset register δεν μπορούμε να ξεφύγουμε από τα όρια του αντίστοιχου segment.

Επίσης πρέπει να αναφέρουμε ότι όταν χρησιμοποιείται μόνο ένας καταχωρητής για να
δηλώσει μια διεύθυνση μνήμης, αυτός δίνει πάντα το offset της διεύθυνσης. Καταχωρητής
segment γενικά θεωρείται εξ΄ορισμού ο DS, εκτός και αν έχουμε τους BP ή SP οι οποίοι
συνδυάζονται εξ΄ορισμού με τον SS, ή τον ΙΡ ο οποίος συνδυάζεται με τον CS.

Μια δεύτερη παρατήρηση που πρέπει να γίνει εδώ είναι το ότι τα διάφορα segments δεν είναι
απαραίτητο να είναι ανεξάρτητα μεταξύ τους, αλλά μπορεί να είναι και επικαλυπτόμενα. Για
παράδειγμα, αν ο σωρός ενός προγράμματος καταλαμβάνει
100Η bytes, τα δεδομένα 50Η bytes και το κυρίως πρόγραμμα 200Η bytes, οι αντίστοιχοι
segment registers μπορεί να έχουν τις εξής τιμές: SS=0100H, DS=0200H και CS=0250H.

Ο τρόπος αυτός οργάνωσης της μνήμης μπορεί να φαίνεται περίπλοκος, έχει όμως ένα
μεγάλο πλεονέκτημα. Τα προγράμματά μας μπορούν εύκολα να επανατοποθετηθούν σε
οποιοδήποτε άλλο σημείο της μνήμης ή σε οποιονδήποτε άλλο υπολογιστή (PC), χωρίς
να χρειαστεί να ξαναγραφούν. Το μόνο που χρειάζεται να γίνει είναι να αλλάξουν τιμές οι
τέσσερις segment registers, κάτι που καθορίζεται αυτόματα από το σύστημα και ο χρήστης
δεν έχει να κάνει τίποτα. Όλοι οι υπόλοιποι καταχωρητές δεν χρειάζεται να πειραχθούν, διότι
δεν αναφέρονται σε απόλυτες διευθύνσεις μνήμης, αλλά σε αποκλίσεις μέσα σε κάποιο
λογικό segment.

2. Ο σωρός (stack)

Επειδή το πλήθος των καταχωρητών του επεξεργαστή είναι πεπερασμένο, χρησιμοποιείται


συχνά το γνωστό τέχνασμα του σωρού (ή στοίβας) για προσωρινή αποθήκευση του
περιεχομένου των καταχωρητών, περιεχομένων θέσεων μνήμης ή άλλων δεδομένων. Η
μονάδα αποθήκευσης και επαναφοράς από τον σωρό είναι πάντα τα 2 byte (16 bits).

Ο σωρός είναι μια περιοχή της μνήμης RAM στην οποία μπορούμε να
7

αποθηκεύσουμε προσωρινά δεδομένα με την λογική LIFO (last in first out). Αυτό σημαίνει
ότι η πρώτη λέξη που θα επανακτήσουμε από το σωρό θα είναι η τελευταία που
αποθηκεύσαμε. Για αποθήκευση και επαναφορά από τον σωρό χρησιμοποιούνται οι εντολές
PUSH και POP αντίστοιχα. Η διεύθυνση της κορυφής του σωρού είναι η SS:SP. Κάθε φορά
που ρίχνουμε κάτι στο σωρό (με την εντολή PUSH), ο σωρός αυξάνει προς τα πάνω
(χαμηλότερες διευθύνσεις) και το περιεχόμενο του SP μειώνεται κατά 2 Αντιθέτως όταν
επαναφέρουμε με την εντολή ΡΟΡ κάτι από τον σωρό το περιεχόμενο του SP αυξάνει κατά
2. Ο σωρός δηλαδή ακολουθεί αντίθετη λογική από την υπόλοιπη μνήμη, στην οποία
τα δεδομένα γράφονται από χαμηλότερες σε υψηλότερες διευθύνσεις.

Το ανώτερο επιτρεπόμενο μέγεθος του σωρού σε ένα πρόγραμμα περιορίζεται από το μέγεθος
ενός segment, δηλαδή 64 Kbytes. Αν προσπαθήσουμε να ξεπεράσουμε τα 64 Kbytes, δεν
πρόκειται να ξεφύγουμε από το segment του σωρού (stack segment) και να καταστρέψουμε
άλλα τμήματα του προγράμματός μας, διότι όπως είπαμε κάθε segment είναι κυκλικό,
δηλαδή η αρχή του γειτονεύει με το τέλος του. Έτσι, αν ο σωρός έχει συμπληρώσει τα
64Kbytes μεγέθους, τα νέα δεδομένα που θα ριχθούν θα πέσουν πάνω σε αυτά που είχαν
τοποθετηθεί αρχικά.

Παράδειγμα:

Αν αρχικά SS=2000H, SP=0502H, AX=0066H και BX=00ACH, οι παρακάτω εντολές:


PUSH AX
PUSH BX
PUSH AX POP
BX POP AX

θα επιφέρουν τις εξής αλλαγές στους καταχωρητές: SS=2000H, SP= 0500H,


AX=00ACH και BX=0066H.

3 Προγραμματισμός σε assembly
Στο κεφάλαιο αυτό θα δούμε την χρήση των ευκολιών του assembler (ψευδοεντολές ή
directives), την δομή ενός προγράμματος σε assembly, καθώς και την χρήση των ρουτινών
του BIOS και του DOS για την ανάπτυξη απλών εφαρμογών.

3.1 Δημιουργία ενός προγράμματος


8

Ο assembler είναι ένα πρόγραμμα που μετατρέπει ένα πρόγραμμα συμβολικής γλώσσας
(assembly) σε γλώσσα μηχανής. Οι πιο δημοφιλείς assemblers για τον 8086 είναι ο MASM
(Microsoft Assembler) και ο TASM (Turbo Assembler). Τα προγράμματα που θα δούμε στην
συνέχεια είναι γραμμένα για τον MASM, αλλά τα περισσότερα από αυτά θα τρέξουν και στον
TASM χωρίς αλλαγές.

Για να δημιουργήσουμε ένα εκτελέσιμο πρόγραμμα πρέπει πρώτα να γράψουμε τον πηγαίο
κώδικα ή κώδικα συμβολικής γλώσσας (assembly). Όπως σε όλες τις γλώσσες
προγραμματισμού, έτσι και στην assembly ο πηγαίος κώδικας πρέπει να είναι ένα αρχείο
κειμένου ASCII του οποίου η προέκταση να φανερώνει από ποια γλώσσα προήλθε. Για την
assembly έχει καθοριστεί η προέκταση των αρχείων του πηγαίου κώδικα να είναι πάντα
.ASM.

Το επόμενο βήμα είναι να περάσουμε το αρχείο από τον assembler, ο οποίος παράγει τον
αντικειμενικό κώδικα (object code). Ο αντικειμενικός κώδικας περιέχει εκτελέσιμο κώδικα
μηχανής και πρόσθετες πληροφορίες σχετικά με την δομή του εκτελέσιμου προγράμματος.
Τα αρχεία αντικειμενικού κώδικα έχουν την προέκταση
.OBJ στο όνομα αρχείου τους.

Τέλος, πρέπει να χρησιμοποιήσουμε το πρόγραμμα σύνδεσης (linker) το οποίο μπορεί να


συνδέσει διαφορετικές λειτουργικές μονάδες αντικειμενικού κώδικα, κάνοντας όλες τις
απαραίτητες συνενώσεις μεταξύ τους και τις μετατρέπει από την μορφή του αντικειμενικού
κώδικα σε ένα πρόγραμμα που μπορεί να φορτωθεί με την μορφή .ΕΧΕ. Τα πιο δημοφιλή
προγράμματα σύνδεσης είναι το LINK και το TLINK.

Εδώ πρέπει επίσης να αναφέρουμε ότι υπάρχει η δυνατότητα δημιουργίας βιβλιοθηκών, οι


οποίες είναι συλλογές από έτοιμες υπορουτίνες σε μορφή αντικειμενικού κώδικα. Αυτές τις
υπορουτίνες μπορούμε να τις χρησιμοποιούμε, χωρίς να τις γράφουμε. Ο linker
αναλαμβάνει να ψάξει μέσα στην βιβλιοθήκη για να βρει και να χρησιμοποιήσει τις
υπορουτίνες που χρειάζονται, ώστε να δημιουργήσει ένα ολοκληρωμένο εκτελέσιμο
πρόγραμμα. Οι βιβλιοθήκες πρέπει να έχουν την επέκταση .LIB στο όνομα αρχείου τους.
Για την διαχείριση των περιεχομένων μιας βιβλιοθήκης χρειάζεται ένα βοηθητικό
πρόγραμμα, που ονομάζεται διαχειριστής βιβλιοθήκης (library manager). Ένα τέτοιο είναι
το LIB του DOS ή ο TLIB της Borland.

3.1.1 Αρχεία COM και ΕΧΕ

Όταν έχουμε μικρά προγράμματα (<64 Κbytes), μπορούμε να τα μετατρέψουμε σε


εκτελέσιμα αρχεία .COM. Στα αρχεία αυτά υπάρχει μόνο ένα segment το οποίο περιέχει τον
κώδικα και τα δεδομένα στο κάτω μέρος του (ξεκινώντας από την απόσταση 100Η). Ένα
πρόγραμμα .COM δεν περιλαμβάνει τμήμα σωρού. Αντί γι΄ αυτό το DOS φορτώνει αυτόματα
9

το πρόγραμμα .COM σε 64 Kbytes μνήμης και τοποθετεί τον σωρό στην κορυφή. Αν λοιπόν
ένα πρόγραμμα είναι κατάλληλο για .COM, μπορούμε να παράγουμε πρώτα το αρχείο .ΕΧΕ
και μετά, με την χρήση της εντολής EXE2BIN που παρέχεται από το DOS, να το
μετατρέψουμε σε .COM. Τα .COM αρχεία καταλαμβάνουν λιγότερο χώρο και φορτώνονται
πιο γρήγορα από τον δίσκο.

Το γεγονός ότι ένα .COM αρχείο μπορεί να χρησιμοποιήσει ένα μόνο λογικό segment,
έχει σαν αποτέλεσμα να μπορεί να τοποθετηθεί οπουδήποτε μέσα στην μνήμη. Αυτό
συμβαίνει διότι χρησιμοποιεί κλήσεις και διακλαδώσεις τύπου NEAR (16μπιτες), άρα
πουθενά μέσα στο πρόγραμμα δεν υπάρχουν απόλυτες διευθύνσεις, παρά μόνο σχετικές.

Αντίθετα, τα .ΕΧΕ προγράμματα, που έχουν πολλά λογικά segments, δεν έχουν την
δυνατότητα να τοποθετούνται οπουδήποτε στην μνήμη. Αυτό εξηγείται ως εξής :

Συνήθως, οι πρώτες εντολές του κυρίως κώδικα ενός προγράμματος είναι οι εξής :

MOV AX, DATA


MOV DS, AX

Με αυτές τις εντολές δίνεται στον DS η τιμή της μεταβλητής DATA που την έχουμε ορίσει
νωρίτερα να δείχνει την διεύθυνση του data segment. Η πρώτη εντολή δεν μπορεί να
μεταφραστεί άμεσα από τον assembler. Αυτό γιατί δεν γνωρίζει όταν το λειτουργικό
πρόγραμμα φορτώσει το πρόγραμμα στην μνήμη, σε ποια διεύθυνση θα αντιστοιχεί το
DATA. Το αποτέλεσμα είναι να μην πάρει τιμή ο ΑΧ μέχρι το πρόγραμμα να φορτωθεί
στην μνήμη. Όταν το πρόγραμμα φορτωθεί στην μνήμη, τότε θα πάρει η εντολή τα
δεδομένα που θα φορτωθούν στον καταχωρητή ΑΧ. Η διαδικασία κατά την οποία τα
δεδομένα γεμίζουν, καλείται επανατοποθέτηση (relocation). Οι πληροφορίες για το που
θα πρέπει να τοποθετηθούν τα δεδομένα κατά την φόρτωση του προγράμματος δίνονται
σε μια περιοχή στην αρχή του αρχείου. Όταν το DOS φορτώσει το αρχείο στην μνήμη,
διαβάζει τις διευθύνσεις αυτές και τοποθετεί τα δεδομένα στις θέσεις που πρέπει.

Έτσι, τα .COM αρχεία μπορούν να φορτωθούν χωρίς καμία διαδικασία επανατοποθέτησης,


ενώ για τα .ΕΧΕ αρχεία πρέπει κάθε φορά που φορτώνονται να δίνουμε τιμές στα νέα
segments που δημιουργούνται.

Αναλυτικά, τα βήματα που γίνονται για να εκτελεστεί ένα .COM αρχείο είναι τα εξής:

1. Στην πρώτη ελεύθερη παράγραφο (παράγραφος = 16 bytes) της κύριας μνήμης


δημιουργείται ο PSP (Program Segment Prefix), ο οποίος είναι ένα σύνολο από 256
bytes που παρέχουν χρήσιμες πληροφορίες στο DOS, σχετικά με το συγκεκριμένο αρχείο,
όπως για παράδειγμα το σύνολο των χαρακτήρων που πιθανών να πληκτρολογήσουμε
10

από την γραμμή εντολής του DOS σαν παραμέτρους στην εκτέλεση του εν λόγω
προγράμματος.
2. Το .COM αρχείο μεταφέρεται από τον δίσκο στην μνήμη αμέσως μετά τον PSP.
3. Όλοι οι segment registers παίρνουν σαν περιεχόμενο την αρχική διεύθυνση του
PSP.
4. O SP παίρνει τιμή FFFEH, δηλαδή η κορυφή του σωρού ορίζεται στο τέλος του
segment. Επίσης δίνεται αυτόματα ένας σωρός μήκους 100Η (256 bytes).
5. O IP παίρνει τιμή 100Η, που σημαίνει ότι το πρόγραμμα αρχίζει από το σημείο αυτό
και κάτω.

Άρα, η δομή ενός .COM προγράμματος όταν αυτό φορτωθεί στη μνήμη είναι:

Τα βήματα που εκτελούνται κατά την φόρτωση για εκτέλεση ενός .ΕΧΕ
προγράμματος είναι τα εξής :

1. Ένα PSP δημιουργείται στην πρώτη ελεύθερη παράγραφο της κύριας μνήμης.
2. Το αρχείο .ΕΧΕ φορτώνεται στην μνήμη από τον δίσκο αμέσως μετά το PSP. To
DOS αναλαμβάνει την επανατοποθέτηση των segments.
3. Οι καταχωρητές DS, ES παίρνουν σαν περιεχόμενο την αρχική διεύθυνση του
PSP.
4. Οι καταχωρητές CS, IP, SS και SP καθορίζονται μέσα από το πρόγραμμα.

Η δομή λοιπόν ενός .ΕΧΕ προγράμματος όταν φορτωθεί στην μνήμη είναι :
11

3.2 Οι ψευδοεντολές (directives) του assembler

Όταν γράφουμε ένα πρόγραμμα σε συμβολική γλώσσα πρέπει εκτός από τις εντολές που
μεταφράζονται άμεσα σε γλώσσα μηχανής (εντολές assembly) να δώσουμε και κάποιες
οδηγίες προς τον assembler που έχουν σχέση με τον ορισμό λογικών segment,
τοποθέτηση δεδομένων στην μνήμη, ορισμό μεταβλητών, σταθερών, υπορουτινών,
μακροεντολών, δομών κτλ. Οι οδηγίες αυτές που είναι απαραίτητες για την δημιουργία του
αντικειμενικού κώδικα, λέγονται ψευδοεντολές ή directives και εξαρτώνται από τον
συγκεκριμένο assembler που χρησιμοποιούμε. Στην συνέχεια θα δούμε τις σημαντικότερες
από αυτές.

3.2.1 Ψευδοεντολές ορισμού δεδομένων

Στα προγράμματα assembly χρησιμοποιούμε κάποια ονόματα για να δηλώνουμε μεταβλητές


(variables), σταθερές (constants) ή ταμπέλες (labels). Τα ονόματα αυτά μπορεί να
αποτελούνται από οποιοδήποτε συνδυασμό των γραμμάτων της αγγλικής αλφαβήτου (Α-Z),
μικρά ή κεφαλαία, τα ψηφία 0-9, καθώς και τα σύμβολα :
? (ερωτηματικό), _ (κάτω παύλα), @ (σύμβολο @) και $ (δολάριο).

Επίσης, ισχύουν οι εξής περιορισμοί :


12

• Το όνομα δεν πρέπει να συμπίπτει με κάποια από τις δεσμευμένες λέξεις του
assembler, τα directives.
• Αναγνωρίζονται μόνο οι πρώτοι 31 χαρακτήρες.
• Μικρά και κεφαλαία γράμματα δεν διακρίνονται μεταξύ τους.
• Ο πρώτος χαρακτήρας δεν μπορεί να είναι ψηφίο (0-9).
• Ο πρώτος χαρακτήρας μπορεί να είναι η τελεία (.).

Οι μεταβλητές (variables) παίρνουν σαν τιμή δεδομένα της μνήμης και μπορεί να έχουν
μέγεθος 1, 2, 4, 8 ή 10 bytes. Το μέγεθος αυτό καθορίζεται με τις ψευδοεντολές ορισμού
δεδομένων (data definition directives). Με τα directives αυτά μπορεί να
γεμίσει μια περιοχή της μνήμης με δεδομένα, και είναι τα εξής :

Αναλυτικότερα, η DB αποθηκεύει ένα ή περισσότερα 8μπιτα δεδομένα σε συνεχόμενες


θέσεις μνήμης. Τα δεδομένα αυτά μπορεί να είναι αριθμοί από το 0 έως το 255 (ή από το –
128 έως το +127 για προσημασμένους), ή ASCII χαρακτήρες, οι οποίοι όμως πρέπει να
τοποθετούνται μέσα σε εισαγωγικά (μονά ή διπλά). Αν δίνονται περισσότερα από ένα
δεδομένα, αυτά ξεχωρίζουν μεταξύ τους με κόμμα. Προαιρετικά μπορεί να δοθεί και το
όνομα μιας μεταβλητής, αριστερά από το directive DB, η οποία αποδίδεται πάντα στην
πρώτη θέση μνήμης.

Τα ίδια ισχύουν και για τα υπόλοιπα directives, με την διαφορά ότι τα δεδομένα ορίζονται
να έχουν μέγεθος 2, 4, 8 ή 10 bytes αντίστοιχα. Εδώ να υπενθυμίσουμε ότι δεδομένα
μεγαλύτερα από 1 byte αποθηκεύονται στην μνήμη με το χαμηλότερης τάξης byte στην
χαμηλότερη διεύθυνση και το υψηλότερης τάξης byte στην υψηλότερη (μεγαλύτερη)
διεύθυνση.

Παραδείγματα :

num1 db 12 Μια θέση μνήμης παίρνει περιεχόμενο το 12 (ή


0CH). Η μεταβλητή num1 ορίζεται να έχει
μέγεθος ένα byte και να συμβολίζει την εν λόγω
θέση μνήμης.
char3 db ‘A’ Η θέση μνήμης char3 παίρνει σαν περιεχόμενο τον
ASCII χαρακτήρα ‘Α’ (41Η).
13

count dw 0AH Η μεταβλητή count παίρνει την τιμή 000ΑΗ, η


οποία αποθηκεύεται σε δυο διαδοχικές θέσεις
μνήμης. Στην πρώτη θέση το 00Η και στην
αμέσως επόμενη το 0ΑΗ.
list dd 12345678H, 0 Εδώ ορίζονται συνολικά 8 θέσεις μνήμης, που θα
έχουν αντίστοιχα τα εξής περιεχόμενα : 78Η, 56Η,
34Η, 12Η, 00Η, 00Η, 00Η, 00Η.
day1 db ‘Κυριακή ’, 0ΑΗ Εδώ γεμίζουν 9 συνολικά θέσεις μνήμης, οι οποίες
θα έχουν αντίστοιχα τα εξής περιεχόμενα :
‘Κ’, ‘υ’, ‘ρ’, ‘ι’, ‘α’, ‘κ’, ‘ή’, ‘ ‘, 0ΑΗ
όπου ότι βρίσκεται μέσα σε εισαγωγικά (ακόμη
και ο χαρακτήρας 'κενό'), μεταφράζεται στον
αντίστοιχο δεκαεξαδικό αριθμό, σύμφωνα με το
πρότυπο ASCII.

Όταν θέλουμε να γεμίσουμε πολλές διαδοχικές θέσεις μνήμης με το ίδιο περιεχόμενο,


μπορούμε να χρησιμοποιήσουμε το directive DUP (duplicate), του οποίου η χρήση
φαίνεται από το επόμενο παράδειγμα :

db 100H dup (‘A’)

όπου εδώ γεμίζουμε 256 (100Η) θέσεις μνήμης με το 41Η (ASCII ισοδύναμο του Α).

Μια σταθερά (constant) μπορεί να πάρει τιμή είτε με το directive EQU, οπότε δεν μπορεί
να αλλάξει τιμή μέσα στο πρόγραμμα, είτε με το directive = , οπότε μπορεί να ξαναοριστεί.

Παράδειγμα :
space1 equ 10
space2 = 12

Τέλος, μια ταμπέλα (label) είναι ένα όνομα που ακολουθείται πάντα από άνω κάτω τελεία
(:), μπορεί να τοποθετηθεί σε οποιοδήποτε σημείο του προγράμματος και αντιπροσωπεύει
την τρέχουσα διεύθυνση του προγράμματος.

Παράδειγμα : L1:
MOV AX, BX JMP
SHORT L1

Μια ταμπέλα μπορεί να συνδυαστεί με το directive LABEL για να του αποδοθεί συνήθως
ο χαρακτηρισμός NEAR ή FAR. Τα directives NEAR, FAR υποδεικνύουν στον assembler
14

αν το συγκεκριμένο όνομα μπορεί να κληθεί μόνο μέσα από το ίδιο segment ή και από
άλλα segments αντίστοιχα. Επίσης, σε εντολές διακλάδωσης μπορεί να χρησιμοποιηθεί
και το directive SHORT που υποδεικνύει στον assembler ότι το άλμα θα είναι short,
δηλαδή από –128 έως +127 θέσεις πάνω ή κάτω (βλέπε και εντολές διακλάδωσης).

3.2.2 Άλλα directives


Άλλα directives που χρησιμοποιούνται συχνά είναι τα εξής :

SEGMENT Υποδεικνύει την αρχή ενός λογικού segment


MACRO Υποδεικνύει την αρχή μιας μακροεντολής ή macro
OFFSET Το directive OFFSET προηγείται μιας μεταβλητής και
υποδεικνύει στον assembler να υπολογίσει το offset της
διεύθυνσης στην οποία αντιστοιχεί η μεταβλητή.
PROC Υποδεικνύει την αρχή μιας υπορουτίνας (procedure)
END Δηλώνει το τέλος του προγράμματος
ENDS Δηλώνει το τέλος ενός λογικού segment
ENDP Δηλώνει το τέλος μιας υπορουτίνας (procedure)
ENDM Δηλώνει το τέλος μιας macro
PTR Το directive PTR (pointer) δηλώνει το μέγεθος (byte ή word)
ενός τελεστή μνήμης, όπου αυτό δεν είναι φανερό. Παράδειγμα :
ΜOV WORD PTR [AX], 0
Με την εντολή αυτή θα μηδενιστούν δύο θέσεις μνήμης : η θέση
DS:[AX] και η DS:[AX+1]
ASSUME Με το directive αυτό αντιστοιχίζουμε ένα λογικό segment σε
έναν ή περισσότερους segment registers.
INCLUDE Με το directive αυτό μπορούμε να περιλάβουμε στο πρόγραμμά
μας κάποιο άλλο πρόγραμμα assembly.
πχ. include ask2.asm

Καλύτερη κατανόηση της χρήσης των directives αυτών, καθώς και παρουσίαση κάποιων
ακόμη, θα γίνει όταν θα αναλύσουμε τα πρώτα προγράμματα, αργότερα στο κεφάλαιο.

3.3 Η δομή ενός προγράμματος


Πριν αρχίσουμε να γράφουμε ένα πρόγραμμα assembly, πρέπει πρώτα να
καθορίσουμε με κάποιο τρόπο την θέση και το μέγεθος των διαφόρων λογικών segment του
προγράμματος. Ένα πρόγραμμα μπορεί γενικά να έχει ένα ή περισσότερα code
segments, όπου περιέχονται ο κυρίως κώδικας και οι υπορουτίνες, ένα ή περισσότερα data
segments, όπου περιέχονται τα δεδομένα και ένα συνήθως stack segment, μέσα στο οποίο
ορίζουμε το μέγεθος του σωρού.
15

Υπάρχουν δύο τρόποι για να αναπτύξουμε ένα πρόγραμμα σε assembly: η χρήση έτοιμων
μοντέλων και η πλήρης ορισμός των λογικών segment του προγράμματος.

3.3.1 Χρήση μοντέλων

Στην περίπτωση αυτή η δομή του προγράμματος επιλέγεται μέσα από κάποια
προκαθορισμένα πρότυπα ή μοντέλα που παρέχει ο MASM. Αυτά επιλέγονται με
χρήση του directive .MODEL και μπορεί να είναι τα εξής :

ΜΟΝΤΕΛΟ ΠΕΡΙΓΡΑΦΗ
Tiny Όλο το πρόγραμμα, δηλαδή κώδικας, δεδομένα και σωρός
περιέχεται μέσα σε ένα και μόνο segment. Έτσι, το μέγεθος του
συνολικού προγράμματος θα είναι ≤ 64Kbytes.
Small Τόσο ο κώδικας, όσο και τα δεδομένα καταλαμβάνουν το
καθένα από ένα segment.
Medium Ένα data segment , ένα ή περισσότερα code segments.
Compact Ένα code segment, ένα ή περισσότερα data segments.
Large Οποιοσδήποτε αριθμός code και data segment
Huge Ίδιο με Large, αλλά επιτρέπονται και data segments > 64
Kbytes.

Το μοντέλο small είναι αυτό που θα μπορούσαμε να χρησιμοποιήσουμε στην


πλειοψηφία των περιπτώσεων. Για να καταλάβουμε την χρήση του, θα δούμε σαν
παράδειγμα ένα πρόγραμμα που όταν το εκτελέσουμε, θα τυπώσει στην οθόνη το
μήνυμα 'ΚΑΛΗΜΕΡΑ!'.

TITLE KALIMERA ;Ο τίτλος του προγράμματος

.MODEL SMALL ;Επιλογή μοντέλου small

.STACK 100h ;Ορισμός μεγέθους του σωρού

.DATA ;Αρχή data segment

MES DB 'ΚΑΛΗΜΕΡΑ!', 0DH, 0AH, '$'

.CODE ;Αρχή code segment


16

MAIN PROC ;Αρχή ρουτίνας MAIN


MOV AX,@DATA ;Με τις δύο αυτές εντολές ο DS MOV
DS, AX ;παίρνει την διεύθυνση του data
;segment
MOV AH, 09
MOV DX, OFFSET MES
INT 21H ;Τύπωμα του buffer MES στην οθόνη

MOV AX, 4C00H


INT 21H ;Έξοδος στο DOS
MAIN ENDP ;Τέλος ρουτίνας MAIN END
MAIN ;Τέλος προγράμματος

Κατ΄ αρχήν να παρατηρήσουμε ότι σε μια σειρά προγράμματος, οτιδήποτε ακολουθεί το


ελληνικό ερωτηματικό ';' (semicolon) θεωρείται σαν σχόλιο και δεν αποτελεί μέρος του
προγράμματος. Ο assembler δηλαδή δεν ασχολείται καθόλου μαζί του.

Στο πρόγραμμα αυτό βλέπουμε κάποια καινούργια directives. Πρώτα το directive TITLE
δεν κάνει τίποτε άλλο, από το να δίνει ένα όνομα στο πρόγραμμα και μπορεί άνετα να
παραληφθεί. Τα directives .DATA και .CODE ορίζουν τα data και code segment αντίστοιχα,
ενώ το .STACK χρησιμοποιείται για να καθορίσουμε το μέγεθος του σωρού. Στο πρόγραμμά
μας καθορίστηκε ο σωρός να έχει ανώτατο μέγεθος 256 (100Η) bytes.

Ακολουθεί η ανάλυση του προγράμματος :

Στο data segment γεμίζουμε ένα buffer μεγέθους 12 bytes με διάφορα δεδομένα. Η αρχική
διεύθυνση του buffer συμβολίζεται με την μεταβλητή ΜΕS. Συγκεκριμένα, αποθηκεύονται
εκεί οι εξής 12 χαρακτήρες:

'Κ', 'Α', 'Λ', 'Η', 'Μ', 'Ε', 'Ρ', 'Α', '!', 0DΗ, 0AΗ, '$'.

Οι χαρακτήρες που περικλείονται σε εισαγωγικά μεταφράζονται στις αντίστοιχες ASCII


τιμές, ενώ τα 0DH και 0AH τοποθετούνται στην μνήμη ως έχουν. Για την ακρίβεια, τα 0DH
και 0ΑΗ είναι οι κωδικοί ASCII των χαρακτήρων ελέγχου carriage return (επιστροφή του
κέρσορα στην αρχή της γραμμής) και line feed (μια γραμμή κάτω) αντίστοιχα.

Το κυρίως πρόγραμμα δεν κάνει τίποτα άλλο από το να καλέσει δύο ρουτίνες του DOS
(αυτό γίνεται με το ΙΝΤ 21Η). Η πρώτη ρουτίνα είναι η συνάρτηση 09 (ΑΗ=09), του ΙΝΤ
21Η, η οποία τυπώνει στην οθόνη τα περιεχόμενα ενός buffer, θεωρώντας ότι αυτά είναι
ASCII χαρακτήρες. Το buffer αυτό θεωρείται ότι ξεκινά στην διεύθυνση DS:DX και
17

τελειώνει όπου υπάρχει ο χαρακτήρας '$'.


Η πιο συχνά χρησιμοποιούμενη συνάρτηση του ΙΝΤ 21H είναι η συνάρτηση 09H, η οποία
εκτυπώνει στην οθόνη μια σειρά χαρακτήρων (string). Η διεύθυνση μνήμης όπου βρίσκεται
ο πρώτος χαρακτήρας της σειράς είναι η DS:DX. Η σειρά τελειώνει με τον χαρακτήρα
'$' (24H), ο οποίος όμως δεν εκτυπώνεται.

Η δεύτερη ρουτίνα που καλεί το πρόγραμμα είναι η ρουτίνα εξόδου στο DOS, η οποία
είναι η συνάρτηση 4CH (ΑΗ=4CH) του ΙΝΤ 21H. Η ρουτίνα αυτή είναι υποχρεωτικό να
υπάρχει στο τέλος κάθε προγράμματος, αλλιώς χάνουμε τον έλεγχο του υπολογιστή. Ας
θυμηθούμε εδώ ότι το MS-DOS ελέγχει τα διάφορα περιφερειακά, όπως το
πληκτρολόγιο και την οθόνη.

Η χρήση των μοντέλων στον προγραμματισμό παρέχει την δυνατότητα να γράφουμε γρήγορα
μικρά προγράμματα, γλιτώνοντάς μας από τον κόπο του αναλυτικού καθορισμού του κάθε
λογικού segment. Έχει όμως το μειονέκτημα ότι πολλά από τα directives που είδαμε δεν
αναγνωρίζονται από όλους τους assemblers (ούτε καν και από τις αρχικές εκδόσεις του
MASM). O TASM για παράδειγμα χρησιμοποιεί τα μοντέλα με λίγο διαφορετικό τρόπο.
Επίσης ο τρόπος αναλυτικού καθορισμού των διαφόρων segments παρέχει καλύτερο έλεγχο
του προγράμματος, και συνήθως προτιμάται, ιδιαίτερα μάλιστα σε μεγάλες εφαρμογές.

3.3.2 Μέθοδος αναλυτικού καθορισμού των segments

Η μέθοδος αυτή καταλήγει σε μεγαλύτερα σε μήκος προγράμματα, αλλά πιο σωστά


δομημένα. Επίσης τα προγράμματα αυτά μπορούν να περάσουν από οποιονδήποτε assembler
χωρίς ιδιαίτερες μετατροπές, καθώς και να χρησιμοποιηθούν από γλώσσες ανωτέρου
επιπέδου (όπως την C και C++). Στην συνέχεια όλες οι εφαρμογές που θα αναπτύξουμε θα
είναι με την μέθοδο αυτή. Καταρχήν ας ξαναδούμε το προηγούμενο πρόγραμμα γραμμένο
σύμφωνα με την μέθοδο του αναλυτικού καθορισμού των segments.

;-----------------------------------------
; σωρός
;-----------------------------------------

STACK SEGMENT stack

DB 0400h DUP ('?') ;ορισμός σωρού μεγέθους 1Κ


STACK_TOP EQU THIS BYTE ;τρέχουσα διεύθυνση μνήμης

STACK ENDS
18

;-----------------------------------------
; δεδομένα
;-----------------------------------------

DATA SEGMENT

MES DB 'KΑΛΗΜΕΡΑ', 0DH, 0AH, '$'

DATA ENDS

;---------------------------------------------
; κώδικας
;---------------------------------------------

CODE SEGMENT

;-----------------------------
; αρχικές συνθήκες
;-----------------------------

MAIN:
ASSUME CS:CODE

MOV AX, DATA ;διεύθυνση DATA στον ΑΧ


MOV DS, AX ;και στον DS ASSUME
DS:DATA
LEA SP,SS:STACK_TOP ;ο SP τίθεται στην κορυφή του σωρού

;-----------------------------
; κυρίως κώδικας
;-----------------------------

MOV AH, 09
LEA DX, MES
INT 21H ;εκτύπωση μηνύματος στην οθόνη

MOV AX, 4C00H


INT 21H ;έξοδος στο DOS

CODE ENDS
END MAIN ;τέλος προγράμματος
19

Η σημαντικότερη διαφορά του προγράμματος αυτού με το προηγούμενο είναι ο ακριβής


καθορισμός των διαφόρων λογικών segments με τα directives SEGMENT και ENDS,
καθώς και το σύνολο των εντολών που αποτελούν τις αρχικές συνθήκες. Οι εντολές αυτές
πρέπει να υπάρχουν σε κάθε πρόγραμμα, και χρησιμεύουν για να αντιστοιχίσουν τα λογικά
segments στους διαφόρους segment registers.

Ένα επίσης νέο στοιχείο είναι το directive THIS το οποίο αντιστοιχίζει την
μεταβλητή STACK_TOP στην τρέχουσα θέση μνήμης, δηλαδή στην κορυφή του σωρού.

Από τα παραπάνω βγαίνει το συμπέρασμα, ότι κάθε πρόγραμμα πρέπει να έχει το εξής
περίγραμμα :

• stack segment
• data segment
• code segment
αρχικές συνθήκες
κυρίως κώδικας έξοδος
στο DOS υπορουτίνες

Κάποιο πρόγραμμα όμως μπορεί να μην έχει data segment, ή αν το πρόγραμμά μας δεν
είναι πολύ μεγάλο, να ορίσουμε ένα λογικό segment τόσο για τα δεδομένα, όσο και για τον
κώδικα. Σε τέτοια περίπτωση θα υπάρχει μόνο stack και code segment, και τα δεδομένα
μπορούν να ορίζονται σε οποιοδήποτε σημείο του code segment (συνήθως τοποθετούνται
στο τέλος). Προσοχή όμως θα πρέπει να δοθεί εδώ στον ορισμό των αρχικών συνθηκών, διότι
θα πρέπει DS=CS.

3.4 Χρήση των ρουτινών του DOS και του BIOS

Το MS-DOS και το BIOS παρέχουν στον χρήστη ένα μεγάλο πλήθος ρουτινών που εκτελούν
πολύ χρήσιμες εργασίες όπως ανάγνωση του πληκτρολογίου, εκτύπωση στην οθόνη και
τον εκτυπωτή, ανάγνωση και εγγραφή σε περιφερειακή μνήμη (σκληρός δίσκος, δισκέτα
κτλ), ανάγνωση και μεταβολή των παραμέτρων του συστήματος και πολλά άλλα. Έτσι
τελικά, ο προγραμματισμός σε assembly ανάγεται σε διαδοχικές κλήσεις ρουτινών (ή
συναρτήσεων) του DOS ή του BIOS και απλή σύνδεση των αποτελεσμάτων. Άλλωστε μια
εφαρμογή, όσο περίπλοκη και αν είναι, μπορεί πάντα να διασπαστεί σε πολλές
απλούστερες εργασίες, οι οποίες θα συνδεθούν κατάλληλα μεταξύ τους.
20

Στο Παράρτημα Β παρέχεται ένας πλήρης κατάλογος των συναρτήσεων του DOS και του
BIOS. Το πλήθος τους είναι τέτοιο, που είναι σχεδόν αδύνατο να τις απομνημονεύσει κανείς.
Το μόνο που χρειάζεται να γνωρίζουμε είναι οι δυο – τρεις συχνότερα χρησιμοποιούμενες,
καθώς και τον τρόπο να διαβάζουμε σωστά τους αντίστοιχους πίνακες.

Μια διακοπή ενεργοποιείται πάντα από μια εντολή ΙΝΤ. Για παράδειγμα η εντολή ΙΝΤ
21H καλεί τις ρουτίνες (συναρτήσεις) του DOS. Οι ρουτίνες αυτές όμως είναι πάρα πολλές.
Το ποια από αυτές θα εκτελεστεί, καθορίζεται από το περιεχόμενο ενός καταχωρητή (του ΑΗ
στην συγκεκριμένη περίπτωση). Η κάθε συνάρτηση είναι μια διεργασία που δέχεται κάποια
δεδομένα σαν είσοδο και βγάζει κάποια άλλα δεδομένα ή εκτελεί μια εργασία σαν έξοδο. Το
τι ακριβώς θα κάνει και από πού θα βρει τα δεδομένα εισόδου (αν χρειάζεται) εξαρτάται από
την ίδια την συνάρτηση.

Τα σημαντικότερα interrupts που θα χρησιμοποιήσουμε είναι τα επόμενα :

• ΙΝΤ 10Η: Ρουτίνες video. Περιλαμβάνονται ρουτίνες για την απεικόνιση


χαρακτήρων και γραφικών στην οθόνη, την κύλιση (scroll) της οθόνης, την θέση του
κέρσορα κτλ.
• ΙΝΤ 14H: Σειριακή επικοινωνία. Ρουτίνες ελέγχου των σειριακών θυρών COM1 και
COM2, όπως για παράδειγμα το modem. Οι ρουτίνες αυτές είναι της μορφής: ανάγνωση
κατάστασης της θύρας, ενεργοποίηση της θύρας, αποστολή και λήψη χαρακτήρα.
• ΙΝΤ 16H: Ρουτίνες πληκτρολογίου. Περιλαμβάνονται οι ρουτίνες ανάγνωσης του
πληκτρολογίου.
• ΙΝΤ 1CΗ: User Timer. Μια άδεια ρουτίνα, η οποία εκτελείται 18.2 φορές το
δευτερόλεπτο και μπορεί να χρησιμοποιηθεί από τα προγράμματα του χρήστη.
• ΙΝΤ 21H: Συναρτήσεις του DOS. Περιλαμβάνεται ένα μεγάλο πλήθος ρουτινών για
είσοδο-έξοδο, διαχείριση αρχείων, διαχείριση μνήμης κτλ. Οι ρουτίνες αυτές είναι
τουλάχιστον 87 και χαρακτηρίζονται από έναν αριθμό (που είναι ο αριθμός της
συνάρτησης) και πρέπει να τοποθετηθεί στον ΑΗ πριν την κλήση της διακοπής.
• ΙΝΤ 33H: Έλεγχος mouse. Ρουτίνες ελέγχου του ποντικιού (mouse).

3.5 Κονσόλα – είσοδος /έξοδος χαρακτήρων

Η εξ ορισμού συσκευή εισόδου για το DOS είναι το πληκτρολόγιο και εξόδου η οθόνη. Οι
συναρτήσεις 00Η έως 0CH του ΙΝΤ 21H χρησιμεύουν για είσοδο και έξοδο χαρακτήρων
για την εξ ορισμού συσκευή εισόδου/εξόδου CON (κονσόλα).

Το DOS χρησιμοποιεί ένα buffer με μέγεθος 15 χαρακτήρων για να τοποθετεί τους


πληκτρολογούμενους χαρακτήρες. Έτσι δεν χάνεται κάτι που πληκτρολογούμε αν τυχόν το
21

DOS δεν έχει προλάβει να επεξεργαστεί τα προηγούμενα. Αν το buffer αυτό γεμίσει, ο


υπολογιστής στέλνει ηχητικό σήμα (beep) και οι επιπλέον χαρακτήρες αγνοούνται. Ο buffer
αυτός ονομάζεται keyboard typeahead buffer.

Κάθε ένας από τους συνηθισμένους χαρακτήρες του πληκτρολογίου, όταν πατηθεί,
δημιουργεί τον αντίστοιχο κωδικό ASCII, ο οποίος τοποθετείται στο buffer που
προαναφέρθηκε. Υπάρχουν όμως και κάποια πλήκτρα, όπως τα πλήκτρα F1-F12, Home, End,
PgUp, Ins, Del, τα βέλη κτλ. τα οποία ονομάζονται πλήκτρα του επεκταμένου
πληκτρολογίου, και δεν αντιστοιχούν σε κάποιο κωδικό ASCII. Η κωδικοποίηση των
πλήκτρων αυτών γίνεται με δύο bytes. Το πρώτο είναι πάντα το
00Η και το επόμενο ονομάζεται scan code και χαρακτηρίζει το συγκεκριμένο πλήκτρο
ή συνδυασμό πλήκτρων (πχ ALT F1). Στους επόμενους πίνακες υπάρχουν οι scan codes για
όλα τα πλήκτρα του επεκταμένου πληκτρολογίου.

Α. Πλήκτρα σε συνδυασμό με το ALT.

Με ALT Scan Code Με ALT Scan Code Με ALT Scan Code


1 78 A 1E N 31
2 79 B 30 O 18
3 7A C 2E P 19
4 7B D 20 Q 10
5 7C E 12 R 13
6 7D F 21 S 1F
7 7E G 22 T 14
8 7F H 23 U 16
9 80 I 17 Y 2F
0 81 J 24 W 11
- 82 K 25 X 2D
= 83 L 26 Y 15
M 32 Z 2C

B. Τα υπόλοιπα πλήκτρα του επεκταμένου πληκτρολογίου

Πλήκτρο Μόνο του Με Shift Με Ctrl Με Alt


F1 3B 54 5E 68
F2 3C 55 5F 69
F3 3D 56 60 6A
F4 3E 57 61 6B
FS 3F 58 62 6C
F6 40 59 63 6D
F7 41 5A 64 6E
F8 42 5B 65 6F
F9 43 5C 66 70
F10 44 5D 67 71
F11 85
F12 86
Home 47 77
22

End 4F 75
PgUp 49 84
PgDn 51 76
PrtSc 37 72
Left arrow 4B 73
Rt arrow 4D 74
Up arrow 48
Dn arrow 50
Ins 52
Del 53
Back tab 0F
Gray + 4E
Gray - 4A

Συνάρτηση 01H: Console Input with Echo

Η συνάρτηση 01 του ΙΝΤ 21H του DOS αναμένει την είσοδο ενός χαρακτήρα από την
κονσόλα (πληκτρολόγιο) και τον τοποθετεί στον AL. Ταυτόχρονα, ο χαρακτήρας εμφανίζεται
και στην οθόνη (echo), κάτι που μπορεί να δημιουργεί πρόβλημα όταν πληκτρολογούμε για
παράδειγμα ένα password. Οι χαρακτήρες ελέγχου (Enter, Backspace, κτλ) απορρίπτονται.

Στο επόμενο παράδειγμα δίνουμε τιμή σε μια μεταβλητή ονόματι char πατώντας ένα
πλήκτρο.

MOV AH, 1
INT 21H
MOV CHAR, AL

Συνάρτηση 02H: Character Output

Ο χαρακτήρας που είναι καταχωρημένος στον DL εκτυπώνεται στην οθόνη.


Προσοχή: Η συνάρτηση αυτή μεταβάλλει και τον AL, γι΄ αυτό καλό είναι να σώζουμε
τον ΑΧ στον σωρό πριν την κλήση της. Το επόμενο παράδειγμα εκτυπώνει τον χαρακτήρα
Α στην οθόνη.

MOV AH, 2
MOV DL, 'A' INT
21H

Συνάρτηση 05H: Printer Output


23

Η συνάρτηση αυτή εκτυπώνει τον χαρακτήρα που περιέχεται στον DL στον


εκτυπωτή, περιμένοντας μάλιστα μέχρι ο εκτυπωτής να είναι έτοιμος. Το επόμενο
παράδειγμα τυπώνει το μήνυμα ΟΚ στον εκτυπωτή.

MOV AH, 5
MOV DL, 'O' INT
21H
MOV DL, 'K'
INT 21H
MOV DL, ODH INT
21H

Ο κωδικός 0DH αντιστοιχεί στον χαρακτήρα ελέγχου carriage return ο οποίος υποδηλώνει
στον εκτυπωτή να εκτυπώσει άμεσα το μήνυμα. Οι περισσότεροι εκτυπωτές τοποθετούν τους
εισερχόμενους χαρακτήρες σε ένα buffer, και τους τυπώνουν όταν το buffer γεμίσει ή όταν
εμφανιστεί το carriage return.

Συνάρτηση 06H: Direct Console Input-Output

Η συνάρτηση αυτή είτε εισάγει είτε εξάγει χαρακτήρες (συμπεριλαμβανομένων των


χαρακτήρων ελέγχου) από/προς την κονσόλα. Αν DL = FFH, τότε γίνεται εισαγωγή του
πρώτου χαρακτήρα που βρίσκεται στο keyboard buffer στον AL. Η εισαγωγή αυτή γίνεται
άμεσα (direct input), δηλαδή χωρίς την αναμονή μέχρι να πατηθεί ένα πλήκτρο, σε αντίθεση
με την συνάρτηση 01H, στην οποία αναμένουμε να πληκτρολογηθεί κάτι. Αν δεν υπάρχει
τίποτα στο buffer, δεν επιστρέφει τίποτα στον AL και το zero flag γίνεται 1.

Αν τώρα ο DL δεν είναι FFH, τότε το περιεχόμενο του DL τυπώνεται στην οθόνη. Η επόμενη
ρουτίνα χρησιμοποιεί την συνάρτηση 06H για να καθαρίσει το keyboard buffer.

CLEAR_KEY_BUF PROC MOV


CX, 15
L1: MOV AH, 6
MOV DL, 0FFH INT
21H
LOOP L1
RET
CLEAR_KEY_BUF ENDP

Συνάρτηση 07H: Console Input Without Echo


24

Η συνάρτηση αυτή περιμένει για έναν χαρακτήρα (συμπεριλαμβανομένων των χαρακτήρων


ελέγχου) από την κονσόλα και τον τοποθετεί στον AL. Ο χαρακτήρας αυτός δεν
εμφανίζεται στην οθόνη. Το CTRL-BREAK δεν είναι ενεργό. Ακριβώς ίδια είναι και η
συνάρτηση 08H, με την μόνη διαφορά ότι το CTRL-BREAK είναι ενεργό.

Συνάρτηση 09H: String Output

Η πιο συχνά χρησιμοποιούμενη συνάρτηση του ΙΝΤ 21H είναι η συνάρτηση 09H, η οποία
εκτυπώνει στην οθόνη μια σειρά χαρακτήρων (string). Η διεύθυνση μνήμης όπου βρίσκεται
ο πρώτος χαρακτήρας της σειράς είναι η DS:DX. Η σειρά τελειώνει με τον χαρακτήρα
'$' (24H), ο οποίος όμως δεν εκτυπώνεται. Στο επόμενο παράδειγμα το όνομα ΝΙΚΟΣ
εμφανίζεται στην οθόνη στην αρχή της επόμενης γραμμής.

NAME DB 0DH, 0AH, 'NIKOΣ', '$'


.
.
.
MOV AH, 9
LEA DX, NAME INT
21H

Συνάρτηση 0ΑΗ: Buffered Console Input

Η συνάρτηση αυτή διαβάζει μια σειρά χαρακτήρων (string) από το πληκτρολόγιο και τους
τοποθετεί σε ένα buffer. Το πλήθος των χαρακτήρων (μήκος του string) μπορεί να είναι
μέχρι 255. Χαρακτήρες του επεκταμένου πληκτρολογίου (όπως τα βέλη, το PgDn κτλ)
απορρίπτονται, ενώ το τέλος του string δηλώνεται με το ENTER.

Το offset της αρχικής διεύθυνσης του buffer τοποθετείται στον DX. Στην πρώτη θέση μνήμης
πρέπει να τοποθετείται το ολικό μήκος του buffer, στην επόμενη τοποθετεί το DOS το πλήθος
των χαρακτήρων που πληκτρολογήθηκαν, χωρίς να υπολογίσει τον χαρακτήρα ENTER, ενώ
οι υπόλοιπες θέσεις μνήμης θα περιέχουν τους χαρακτήρες αυτούς και το ENTER (0DH).
Το επόμενο παράδειγμα δημιουργεί ένα buffer 50 χαρακτήρων και περιμένει είσοδο από το
πληκτρολόγιο.

BUF_SIZE DB 50
CHAR_BUF DB 51 DUP (0)
.
25

.
.
MOV AX, 0AH
LEA DX, BUF_SIZE INT
21H

Το CHAR_BUF ορίστηκε να έχει μέγεθος 51 bytes, διότι το πρώτο byte θα περιέχει το


πλήθος των πληκτρολογημένων χαρακτήρων, και στα υπόλοιπα θα μπορούν να εισαχθούν
μέχρι και 50 χαρακτήρες από το πληκτρολόγιο.

Συνάρτηση 0ΒΗ: Get Console Input Status

Η συνάρτηση αυτή εξετάζει το buffer του πληκτρολογίου για να δει αν βρίσκεται εκεί κάποιος
χαρακτήρας. Αν υπάρχει κάποιος χαρακτήρας, το DOS επιστρέφει FFH στον AL, αλλιώς
επιστρέφει το 00Η.

Συνάρτηση 0CH: Clear Input Buffer, Invoke Input Function

Η συνάρτηση αυτή καθαρίζει το buffer του πληκτρολογίου και καλεί μια από τις συναρτήσεις
εισόδου κονσόλας, δηλαδή μία από τις 01H, 06H, 07H ή 08H. Ο αριθμός της
συνάρτησης που θα καλέσουμε πρέπει να βρίσκεται στον AL. Στην έξοδο, ο AL θα
περιέχει τον χαρακτήρα που πληκτρολογήσαμε. Το επόμενο παράδειγμα καθαρίζει τον
keyboard buffer, και εισάγει έναν χαρακτήρα στην μεταβλητή ΝΑΜΕ, μέσω της συνάρτησης
07H.

MOV AH, 0CH MOV


AL, 07
INT 21H
ΜΟV NAME, AL

Ένας πιο άμεσος τρόπος για εισαγωγή από το πληκτρολόγιο είναι η χρήση των συναρτήσεων
του ΙΝΤ 16H του BIOS. Στο Παράρτημα Β αναφέρονται όλες αυτές αναλυτικά. Η συνάρτηση
00Η (ΑΗ=0), για παράδειγμα, περιμένει μέχρι να πατηθεί κάποιο πλήκτρο και όταν αυτό
συμβεί, ο αντίστοιχος κώδικας ASCII αποθηκεύεται στον AL. Αν αυτό είναι πλήκτρο του
επεκταμένου πληκτρολογίου, αποθηκεύεται στον AL το 00Η και στον ΑΗ το scan code του
πλήκτρου.
26

3.6 Απεικόνιση στην οθόνη

Όταν μια εφαρμογή θέλει να τυπώσει κάποιον χαρακτήρα στην οθόνη, έχει δύο επιλογές. Να
γράψει απευθείας στο video buffer ή να χρησιμοποιήσει τις κατάλληλες συναρτήσεις του
ΙΝΤ 10Η του BIOS.

Απευθείας εγγραφή στο video buffer: Το video buffer είναι μια περιοχή της μνήμης στην
οποία είναι τοποθετημένα τα περιεχόμενα της τρέχουσας οθόνης. Η διεύθυνση του video
buffer, το μέγεθός του, καθώς και η κωδικοποίηση των περιεχομένων του, εξαρτάται από
την κάρτα γραφικών που χρησιμοποιούμε και πιθανόν το συγκεκριμένο σύστημα στο
οποίο δουλεύουμε. Τα περιεχόμενα του video buffer διαβάζονται συνεχώς και απεικονίζονται
στα κατάλληλα σημεία της οθόνης. Αν μια θέση μνήμης του video buffer αλλάξει
περιεχόμενο, στην επόμενη ανάγνωση (δηλαδή σε λίγα ms) θα αλλάξει και ο αντίστοιχος
χαρακτήρας (ή pixel αν έχουμε οθόνη γραφικών). Οι εφαρμογές που γράφουν απευθείας
στο video buffer είναι ταχύτατες αλλά δεν μπορούν να λειτουργήσουν το ίδιο σε όλα τα
συστήματα ούτε σε όλους τους τρόπους απεικόνισης (video modes).

Χρήση των ρουτινών του BIOS και του DOS: To INT 10H του BIOS παρέχει αρκετές
συναρτήσεις για απεικόνιση στην οθόνη. Η χρήση τους είναι η ίδια σε όλα τα συστήματα,
αλλά οπωσδήποτε υπάρχει κάποια καθυστέρηση σε σχέση με την απευθείας εγγραφή
στο video buffer. Μπορούν επίσης να χρησιμοποιηθούν και κάποιες ρουτίνες του DOS, αλλά
εκεί η καθυστέρηση είναι μεγάλη.

Γενικές έννοιες

Τα πρώτα χρόνια του PC υπήρχαν μόνο οι κάρτες οθόνης MDA (monochrome display
adapter) για μονόχρωμο κείμενο, CGA (color graphics adapter) και EGA (enhanced
graphics adapter) για κείμενο και γραφικά χαμηλής ανάλυσης. Από το
1991 και μετά έκαναν την εμφάνισή τους οι κάρτες VGA (video graphics array) με τις οποίες
μπορούμε να έχουμε πολύ καλές αναλύσεις και μεγάλο αριθμό χρωμάτων. Στον επόμενο
πίνακα φαίνονται οι βασικές κάρτες που χρησιμοποιούνται στο PC και
οι μέγιστες αναλύσεις τους.

Τύπος display Μέγιστη ανάλυση Χρώματα


στήλες * γραμμές
MDA μόνο κείμενο -
CGA 640 Χ 200 2
EGA 640 Χ 350 16
27

MCGA 640 Χ 480 2


VGA 640 Χ 480 16
Super VGA 800 Χ 600 16
Extended VGA 1024 Χ 768 256

Video Modes : Μπορούμε να έχουμε δύο τύπους οθόνης (video modes): κείμενο και
γραφικά. Όταν βρισκόμαστε σε text mode στην οθόνη μπορούν να εμφανιστούν μόνο οι
χαρακτήρες του πληκτρολογίου (και οι επεκταμένοι), οι οποίοι αντιστοιχούν σε όλα τα
ASCII σύμβολα. Τα χρώματα μπορεί να είναι ένα ή περισσότερα. Όταν βρισκόμαστε σε
graphics mode μπορούμε να απεικονίσουμε οποιοδήποτε σχήμα, ενεργοποιώντας
κατάλληλα τις στοιχειώδεις ψηφίδες (pixels) της οθόνης. Το μέγεθος των pixels αυτών είναι
τόσο μικρότερο, όσο μεγαλύτερη είναι η ανάλυση. Τα pixels μπορούν να έχουν ένα ή
περισσότερα χρώματα. Μερικά από τα πιο συνηθισμένα modes και οι κάρτες που τα
υποστηρίζουν φαίνονται στον επόμενο πίνακα.

Mode Περιγραφή MDA CGA EGA MCGA VGA


2 Κείμενο, 80Χ25, 16 χρώματα X X X X
3 Κείμενο, 80Χ25, 16 χρώματα X X X X
7 Κείμενο, 80Χ25, μονόχρωμο X X X
16 Γραφικά, 640Χ350, 16 χρώματα X X
17 Γραφικά, 640Χ480, 2 χρώματα X X
18 Γραφικά, 640Χ480, 16 χρώματα X
19 Γραφικά 320Χ200 256 χρώματα X X

Video Attributes: Όταν έχουμε οθόνη κειμένου, κάθε χαρακτήρας αντιστοιχεί σε δύο
bytes : ένα για τον κώδικα ASCII του χαρακτήρα και ένα για το attribute. Το attribute
είναι ένα byte που φανερώνει τον τρόπο εμφάνισης του χαρακτήρα, δηλαδή το χρώμα του,
αν θα είναι υπογραμμισμένος, έντονα φωτισμένος (highlight) ή αν αναβοσβήνει (blinks).
Για μονόχρωμη οθόνη κειμένου (video mode 7) τα διάφορα
attributes μπορεί να είναι τα εξής:

Τιμή Attribute
07H Κανονικό
28

0FH Φωτεινό (highlight)


70H Ανάστροφο (inverse)
01H Υπογράμμιση
09H Φωτεινή υπογράμμιση

Αν το MSB (bit 7) του attribute γίνει 1, τότε ο χαρακτήρας αναβοσβήνει. Για παράδειγμα,
το attribute 81H σημαίνει χαρακτήρας υπογραμμισμένος που αναβοσβήνει.

Σε έγχρωμο mode κειμένου (mode 3), το attribute δείχνει και το χρώμα του χαρακτήρα.
Εδώ δεν μπορούμε να έχουμε την επιλογή της υπογράμμισης, αλλά υπάρχει το
αναβόσβημα, η ανάστροφη εμφάνιση (reverse video) και η φωτεινότητα. Σε έναν
χαρακτήρα στην οθόνη ορίζονται δύο χρώματα: το foreground που είναι το χρώμα του
χαρακτήρα, και το background που είναι το χρώμα του υπόβαθρου, δηλαδή το χρώμα
της οθόνης πίσω από τον χαρακτήρα. Τα bits 0, 1 και 2 του attribute δείχνουν το
foreground color, ενώ τα bits 4, 5, και 6 δείχνουν το χρώμα του background. Το bit 3
δείχνει την φωτεινότητα του χρώματος foreground, δηλαδή αν είναι 1 τα χρώματα
γίνονται πιο ανοικτά. Έτσι στην ουσία είναι σαν να έχουμε 16 χρώματα για το
foreground. To bit 7 είναι το bit ενεργοποίησης του αναβοσβήματος. Στην κάρτα EGA
όμως το bit 7 έχει διπλή σημασία: Μπορεί να ρυθμίζει είτε το αναβόσβημα (blinking), είτε
την φωτεινότητα του background, επιτρέποντάς του έτσι να έχει και αυτό 16 χρώματα.
Η σημασία του bit 7 σε αυτή την περίπτωση καθορίζεται από την υποσυνάρτηση 03H
της συνάρτησης 10Η του ΙΝΤ 10Η (βλέπε και Παράρτημα Β). Οι κωδικοί των 16 αυτών
χρωμάτων φαίνονται στον ακόλουθο
πίνακα:

Bit φωτεινότητας = 0 Bit φωτεινότητας = 1


000 μαύρο 000 γκρι
001 μπλε 001 γαλάζιο
010 πράσινο 010 ανοικτό πράσινο
011 κυανό 011 ανοικτό κυανό
100 κόκκινο 100 ανοικτό κόκκινο
101 μωβ (magenta) 101 ανοικτό μωβ
110 καφέ 110 κίτρινο
111 λευκό 111 φωτεινό λευκό

Στην συνέχεια θα δούμε ορισμένες από τις συναρτήσεις του ΙΝΤ 10Η του BIOS. Οι
ρουτίνες αυτές σώζουν τους segment registers και τους BX, CX, DX. Τους
υπόλοιπους πρέπει να τους σώζουμε εμείς αν χρειάζεται.
29

Συνάρτηση 00Η του ΙΝΤ 10Η: Set Video Mode

Με την συνάρτηση αυτή μπορούμε να αλλάξουμε το τρέχον video mode. Αρκεί να


τοποθετήσουμε τον αριθμό του νέου video mode στον AL. Όλα τα video modes
παρουσιάζονται αναλυτικά στο Παράρτημα Β. Αν για παράδειγμα επιθυμούμε μονόχρωμο
κείμενο, επιλέγουμε mode 7 ως εξής:

MOV AH, 0
MOV AL, 7
INT 21H

Μόλις εκτελεστούν οι παραπάνω εντολές, καθαρίζει ο οθόνη και βρισκόμαστε στο νέο
mode. Αν δεν θέλουμε να καθαρίσει η οθόνη, μπορούμε να θέσουμε 1 το ΜSB (bit 7)
του AL. Στο παράδειγμά μας θα έπρεπε να γράψουμε : MOV AL, 87H.

Συνάρτηση 01H του ΙΝΤ 10Η: Set Cursor Lines

Ο δείκτης κειμένου (cursor) είναι ένα ορθογώνιο παραλληλόγραμμο με ύψος 1/25 της οθόνης
και πλάτος 1/80 του πλάτους της οθόνης (για οθόνη κειμένου 80Χ25), καταλαμβάνει δηλαδή
τον ίδιο χώρο με έναν χαρακτήρα. Το ορθογώνιο αυτό χωρίζεται σε 13 γραμμές για
μονόχρωμη οθόνη και 8 γραμμές για τις υπόλοιπες οθόνες. Η εμφάνιση του cursor εξαρτάται
από το πόσες από αυτές τις γραμμές είναι ενεργοποιημένες (φωτεινές). Το τυπικό είναι να
ενεργοποιούνται μόνο οι δύο τελευταίες γραμμές (βλέπε σχ. 4.1), οπότε ο cursor έχει την
γνωστή εμφάνιση της αναβοσβήνουσας παχιάς οριζόντιας γραμμής στο κάτω μέρος της
συγκεκριμένης
θέσης της οθόνης.

Σχήμα 3.1 Cursor έγχρωμης και μονόχρωμης οθόνης


30

Με την συνάρτηση 01H του ΙΝΤ 10Η μπορούμε να καθορίσουμε το μέγεθος του κέρσορα.
Αρκεί να τοποθετήσουμε στον CH την αρχική και στον CL την τελική γραμμή. Για τυπικό
cursor σε μονόχρωμη οθόνη θα είναι CH=0BH και CL=0CH, ενώ για έγχρωμη οθόνη οι ίδιοι
καταχωρητές θα πρέπει να έχουν τιμές 06H και 07H αντίστοιχα.

Συνάρτηση 02Ητου ΙΝΤ 10Η: Set Cursor Position

Με την συνάρτηση αυτή τοποθετούμε τον cursor στην θέση που επιθυμούμε. Ο DL πρέπει
να περιέχει την στήλη (0-79), ο DH την γραμμή (0-24) και ο ΒΗ την τρέχουσα σελίδα της
οθόνης (συνήθως 0). Σε ένα video buffer μπορεί να είναι τοποθετημένες περισσότερες από
μία οθόνες (ή σελίδες όπως ονομάζονται), από τις οποίες όμως μόνο μία μπορεί να είναι
ενεργή, δηλαδή να εμφανίζεται. Το επόμενο παράδειγμα, θέτει mode 3 (έγχρωμο κείμενο),
μέγιστο μέγεθος κέρσορα και τοποθετεί τον κέρσορα στην μέση της οθόνης.

MOV AH, 0 ;καθάρισμα της οθόνης και


MOV AL, 3 ;αλλαγή σε mode 3
INT 10H MOV
AH, 1
MOV CX, 0007H ;μέγιστο μέγεθος cursor σε έγχρωμη οθόνη
INT 10H
MOV AH, 2 ;τοποθέτηση του cursor
MOV DL, 40 ;στη θέση 40Χ12 (κέντρο οθόνης) MOV
DH, 12
MOV BH, 0 ;στη σελίδα 0
INT 10H

Συνάρτηση 03 του ΙΝΤ 10Η: Get Cursor

Η συνάρτηση αυτή μας επιστρέφει το μέγεθος και την θέση του cursor.
Συγκεκριμένα, η αρχική γραμμή του μεγέθους του cursor τοποθετείται στον CH, η τελική
γραμμή στον CL, η στήλη της θέσης στον DL και η γραμμή στον DH. Η συνάρτηση αυτή
είναι ιδιαίτερα χρήσιμη σε προγράμματα που χρησιμοποιούν μενού. Με την κλήση της και
ορισμένες συγκρίσεις, μπορούμε να αποφανθούμε ποιο μενού έχει επιλεγεί.

Συναρτήσεις 06H και 07H του ΙΝΤ 10Η: Scroll Window

Με τις συναρτήσεις 06H (scroll window up) και 07H (scroll window down) μετακινούμε τα
31

δεδομένα ενός παραθύρου της οθόνης πάνω ή κάτω αντίστοιχα. Όταν για παράδειγμα ένα
παράθυρο μετακινείται προς τα πάνω (scrolls up) οι πάνω γραμμές χάνονται και στην
θέση των κάτω γραμμών που ανεβαίνουν, εισάγονται κενές γραμμές.

Σαν παράθυρο (window) ορίζεται μια ορθογώνια περιοχή της οθόνης, η οποία καθορίζεται
από τις συντεταγμένες του πάνω αριστερά και του κάτω δεξιά σημείου της. Με τον ορισμό
αυτό, ολόκληρη η οθόνη μπορεί να θεωρηθεί ένα παράθυρο με συντεταγμένες (0,0) και
(79, 24), όταν έχουμε κείμενο ανάλυσης 80Χ25. Στις συντεταγμένες οποιουδήποτε σημείου
της οθόνης πρώτα αναφέρουμε τις στήλες και μετά τις γραμμές.

Κατά την κλήση των συναρτήσεων 06H, 07H χρησιμοποιούνται οι εξής


καταχωρητές:

Καταχωρητής Σημασία
AL Αριθμός γραμμών (0=όλες)
CH Γραμμή της πάνω αριστερά γωνίας του
παραθύρου
CL Στήλη της πάνω αριστερά γωνίας του παραθύρου
DH Γραμμή της κάτω δεξιά γωνίας του παραθύρου
DL Στήλη της κάτω δεξιά γωνίας του παραθύρου
BH Attribute των κενών γραμμών που θα εισαχθούν

Ένα πρόγραμμα που καθαρίζει την οθόνη είναι το εξής:

MOV AH, 6 ;μετακίνησε παράθυρο προς τα πάνω


MOV AL, 0 ;όλες οι γραμμές της οθόνης MOV
CH, 0 ;συντεταγμένες πάνω αριστερά: MOV
CL, 0 ;(0,0)
MOV DH, 24 ;συντεταγμένες κάτω δεξιά:
MOV DL, 79 ;(79,24)
MOV BH, 7 ;normal attribute
INT 10H

Συνάρτηση 08H του ΙΝΤ 10Η: Read Character and Attribute

Με την συνάρτηση αυτή διαβάζουμε τον χαρακτήρα που βρίσκεται στην τρέχουσα
θέση του cursor καθώς και το αντίστοιχο attribute. Συγκεκριμένα:

Παράμετροι εισόδου: AH
32

= 08H
BH = αριθμός σελίδας οθόνης

Παράμετροι εξόδου: AL
= χαρακτήρας ΑΗ =
attribute

Συνάρτηση 09H του ΙΝΤ 10Η: Write Character and Attribute

Με την συνάρτηση αυτή μπορούμε να γράψουμε έναν χαρακτήρα και attribute σε μία ή
περισσότερες διαδοχικές θέσεις στην οθόνη. Συγκεκριμένα:

Παράμετροι εισόδου:
ΑΗ = 09H
AL = χαρακτήρας
ΒΗ = αριθμός σελίδας οθόνης
BL = attribute
CX = αριθμός επαναλήψεων

Έξοδος:
Ο χαρακτήρας και το attribute που δόθηκαν γράφονται από την τρέχουσα θέση του
cursor και κάτω, τόσες φορές όσες υποδεικνύει το περιεχόμενο του CX.

Με την συνάρτηση αυτή του ΙΝΤ 10Η μπορούν να γραφούν όλοι οι χαρακτήρες ASCII,
ακόμη και αυτοί με κωδικούς από 1 έως 31, οι οποίοι κανονικά χρησιμοποιούνται ως
χαρακτήρες ελέγχου. Εδώ όμως αυτοί οι κωδικοί παριστάνουν κάποια γραφικά σύμβολα, πχ
ο κωδικός 21 παριστάνεται σαν §.

Συνάρτηση 0ΑΗ του ΙΝΤ 10Η: Write character

Η συνάρτηση αυτή είναι ακριβώς ίδια με την 09H, με την διαφορά ότι εδώ δεν
αλλάζουμε το attribute.

Συνάρτηση 0FH του ΙΝΤ 10Η: Get Video Mode

Η συνάρτηση αυτή επιστρέφει το τρέχον video mode ως εξής:


33

Είσοδος:
ΑΗ = 0FH

Έξοδος:
ΑΗ = αριθμός στηλών της οθόνης
AL = video mode
BH = ενεργός σελίδα οθόνης

Η συνάρτηση αυτή πρέπει να καλείται και τα αποτελέσματά της να σώζονται, πριν


επιχειρήσουμε να αλλάξουμε video mode για να πάμε για παράδειγμα σε ένα mode
γραφικών. Στο τέλος του προγράμματος, και λίγο πριν ξαναβγούμε στο DOS, θα πρέπει να
επαναφέρουμε το default mode κειμένου, έτσι ώστε στην γραμμή εντολών του DOS να
έχουμε το γνωστό περιβάλλον.
34

ΠΑΡΑΡΤΗΜΑ Α

Η Γλώσσα Assembly του 8086

1. Κατηγορίες Εντολών
Όλες οι εντολές της γλώσσας assembly του 8086 δίνονται στο Παράρτημα Α με αλφαβητική
σειρά και με συνοπτική επεξήγηση της λειτουργίας τους. Συνολικά αυτές μπορούν να
ομαδοποιηθούν σε 7 κατηγορίες, ανάλογα με τον σκοπό που εξυπηρετούν.

1. Μεταφοράς δεδομένων.
2. Αριθμητικές και λογικές.
3. Ολίσθησης και περιστροφής.
4. Χειρισμού αλφαριθμητικών (strings).
5. Χειρισμού των flags.
6. Ελέγχου προγράμματος.
7. Ελέγχου του μικροεπεξεργαστή.

Στην συνέχεια θα αναλύσουμε την λειτουργία των βασικότερων εντολών κάθε


ομάδας.

2. Εντολές μεταφοράς δεδομένων

Η ομάδα αυτή γενικά περιλαμβάνει εντολές που μεταφέρουν δεδομένα ανάμεσα στον
επεξεργαστή (καταχωρητές), την μνήμη και τις συσκευές εισόδου/εξόδου (Ι/Ο). Συνολικά
αυτές είναι οι : MOV, PUSH, POP, PUSHF, POPF, XCHG, XLAT, IN, OUT, LEA, LDS,
LES, CBW, CWD, LAHF και SAHF.

2.1 Η εντολή MOV

Με την εντολή MOV μπορούμε να μεταφέρουμε δεδομένα (bytes ή words) από καταχωρητή
σε καταχωρητή, από καταχωρητή σε θέση μνήμης και αντίστροφα, καθώς και να δώσουμε
άμεσα τιμές τόσο σε καταχωρητές όσο και σε θέσεις μνήμης. Όλα αυτά μπορούν να γίνουν
με πολλούς τρόπους, όσοι και οι τρόποι προσπέλασης της μνήμης και έτσι οδηγούμαστε σε
πάρα πολλούς συνδυασμούς της εντολής αυτής.

Η σύνταξη της εντολής έχει ως εξής :


35

MOV dest, source

όπου το περιεχόμενο της παραμέτρου πηγής (source) αντιγράφεται στην παράμετρο


προορισμού (dest). Η παράμετρος dest μπορεί να είναι οποιοσδήποτε καταχωρητής ή θέση
μνήμης, ενώ η παράμετρος πηγής μπορεί να είναι καταχωρητής, θέση μνήμης ή άμεσα
διδόμενος αριθμός. Οι μόνοι συνδυασμοί που δεν επιτρέπονται είναι άμεση τιμή σε segment
register, segment register σε segment register και από θέση μνήμης σε θέση μνήμης.
Αυτονόητο βέβαια είναι ότι οι παράμετροι πηγής και προορισμού πρέπει να είναι του ίδιου
μεγέθους (δηλ. είτε 8μπιτοι είτε 16μπιτοι).

Εδώ πρέπει να αναφέρουμε ότι μια θέση μνήμης μπορεί να παρασταθεί με πολλούς
τρόπους (addressing modes). Αυτοί είναι :

• Άμεσος : Δίνεται η ίδια η διεύθυνση ή ένα label το οποίο έχει αντιστοιχηθεί στην
διεύθυνση αυτή. Π.χ. [00Α0Η] ή list1. Η διεύθυνση αυτή είναι το offset. Segment
θεωρείται πάντα ο DS, εκτός αν αναφέρεται άλλος segment register.
• Έμμεσος : Η διεύθυνση της θέσης (offset) βρίσκεται στο περιεχόμενο ενός
καταχωρητή. Για τον σκοπό αυτό μπορούν να χρησιμοποιηθούν μόνο οι καταχωρητές
βάσης ΒΧ και ΒΡ, καθώς και οι δείκτες SI, DI.
• Βάση συν δείκτης : Το offset της διεύθυνσης βρίσκεται αν προσθέσουμε τα
περιεχόμενα των εν λόγω καταχωρητών (στο άθροισμα κρατάμε τα 16
χαμηλότερα bit). Π.χ. [ΒΧ+SI], [BP+DI].
• Βάση (ή δείκτης) συν μετατόπιση : π.χ. [ΒΧ+5] ή array[BX]. Στην πρώτη
περίπτωση η διεύθυνση που προκύπτει έχει offset το περιεχόμενο του ΒΧ συν 5, ενώ στο
δεύτερο παράδειγμα υπολογίζεται το offset του array και σε αυτό προστίθεται το
περιεχόμενο του ΒΧ.
• Βάση συν δείκτης συν μετατόπιση : π.χ. [ΒΡ+SI+4] ή table[ΒΧ+DI].

Παραδείγματα :

MOV AL, BL Αντιγραφή του BL στον AL. MOV


DS, BX Αντιγραφή του ΒΧ στον DS MOV
AX, 32H Αντιγραφή του 0032H στον ΑΧ
MOV BX, “AB” Αντιγραφή των ASCII ΑΒ στον ΑΧ (AL=42H
AH=41H).
MOV AX, NIKOS Αντιγράφει την λέξη που βρίσκεται στην διεύθυνση
NIKOS του data segment στον ΑΧ.
MOV [0500H], AL Αντιγράφει το περιεχόμενο του AL στην διεύθυνση
DS:0500H.
36

MOV [BP], AH Αντιγράφει τον ΑΗ στην διεύθυνση SS:BP.


Θυμηθείτε ότι ο ΒΡ συνδυάζεται εξ ορισμού με τον SS.

MOV [BX+SI], SP Αντιγράφει τον SP στην διεύθυνση με segment DS και


offset BX+SI.
MOV BH, LIST[DI+3] Αντιγράφει στον ΒΗ το περιεχόμενο (byte) της
διεύθυνσης του data segment με offset το offset του LIST
συν DI συν 3.
MOV BX, AL Δεν επιτρέπεται (από 8 σε 16 bit).
MOV DS, ES Δεν επιτρέπεται (από segment reg. σε segment reg.). MOV
CS, AX Δεν επιτρέπεται (ο CS δεν μπορεί να είναι η
παράμετρος προορισμού.
MOV [SI], [BX] Δεν επιτρέπεται (μεταφορά από μνήμη σε μνήμη).

2.2 Οι εντολές PUSH και ΡΟΡ

Η εντολή PUSH αντιγράφει μια λέξη στον σωρό και μειώνει τον SP κατά 2, ενώ η εντολή
ΡΟΡ αντιγράφει την λέξη που βρίσκεται στην κορυφή του σωρού στην παράμετρο που την
ακολουθεί.

Παραδείγματα :
PUSH AX Αντιγράφει το περιεχόμενο του ΑΧ στον σωρό.
ΡΟΡ ΒΧ Αντιγράφει στον ΒΧ την λέξη που βρίσκεται στην κορυφή του
σωρού.
PUSH ABCDH Αντιγράφει τον αριθμό ΑΒCDH στην κορυφή του σωρού.
PUSH WORD PTR [BX] Αντιγράφει στον σωρό την λέξη που βρίσκεται στην
διεύθυνση DS:BX. Tο directive WORD PTR δηλώνει ότι
στην αντίστοιχη διεύθυνση βρίσκεται word και όχι byte. (βλ.
αντίστοιχο κεφάλαιο για τα directives).
PUSH ‘A’ Αντιγράφει τον ASCII χαρακτήρα ‘Α’ σαν δύο byte
στον σωρό, δηλ. αντιγράφει το 0041H.
PUSHF Αντιγράφει τον flag register στον σωρό.
POPF Αντιγράφει την κορυφή του σωρού στον flag register. POP
CS Δεν επιτρέπεται να γράφουμε τίποτα στον CS.

2.3 Οι εντολές LEA, LDS, LES

Η εντολή LEA υπολογίζει και φορτώνει το offset ενός τελεστή μνήμης σε έναν
37

καταχωρητή.

Παράδειγμα :

LEA AX, NAME1 Φορτώνει στον ΑΧ το offset του ΝΑΜΕ1.

Η εντολή αυτή είναι ίδια με την MOV AX, OFFSET NAME1, όπου το directive OFFSET
επιβάλει στον επεξεργαστή να υπολογίσει το offset του τελεστή ΝΑΜΕ1 (βλ. αντίστοιχο
κεφάλαιο για τα directives του assembler).

Η εντολή LDS αντιγράφει 4 bytes από μια θέση μνήμης που δίνεται σαν παράμετρος σε
κάποιον καταχωρητή (που επίσης δίνεται σαν παράμετρος) και στον DS. H LES κάνει την
ίδια δουλειά αλλά χρησιμοποιεί τον ES (βλ. και παράρτημα Α).

Παράδειγμα :

LDS AX, DATE Αντιγράφει στον ΑΧ τα περιεχόμενα των διευθύνσεων DATE


και DATE + 1 και στον DS τα περιεχόμενα των DATE + 2
και DATE + 3.

2.4 Οι εντολές εισόδου / εξόδου (ΙΝ και OUT)

Οι εντολές ΙΝ και OUT χρησιμεύουν για την μεταφορά δεδομένων μεταξύ του επεξεργαστή
και των συσκευών εισόδου / εξόδου (Ι/Ο). Για τον σκοπό αυτό χρησιμοποιούνται οι
καταχωρητές AL ή ΑΧ για την μεταφορά byte ή λέξεων αντίστοιχα. Η διεύθυνση της θύρας
(port) εισόδου/εξόδου μπορεί να δοθεί είτε άμεσα σαν 8μπιτος αριθμός, είτε έμμεσα σαν
16μπιτος αριθμός μέσω του DX. Αυτό φαίνεται καλύτερα στα παραδείγματα που
ακολουθούν.

Παραδείγματα :

IN AL, 42H 8 bits εισάγονται στον AL από την θύρα 42H. OUT
6BH, AX Το περιεχόμενο του ΑΧ εξάγεται στην θύρα 6ΒΗ.
ΙΝ ΑX, DX 16 bits εισάγονται στον AX από την θύρα που δείχνει ο DX. OUT
DX, AL Το περιεχόμενο του ΑL εξάγεται στην θύρα που δείχνει ο DX.

Στον 8086 οι διευθύνσεις των θυρών είναι 16μπιτοι αριθμοί, καταλαμβάνουν δηλαδή τις 16
κατώτερες θέσεις του address bus (A0-A15). To περιεχόμενο των ακροδεκτών Α16-Α19 είναι
αδιάφορο. Όταν η διεύθυνση μιας θύρας δίνεται σαν 8μπιτος αριθμός, αυτός επεκτείνεται σε
16μπιτο θέτοντας 0 τα 8 υψηλότερης τάξης bit. Αυτά φαίνονται καλύτερα στο σχήμα 1 που
38

περιγράφει το περιεχόμενο των ακροδεκτών που επηρεάζονται κατά την εκτέλεση της
εντολής OUT 25H, AX.

Σχ. 1 Τα σήματα που παράγονται κατά την εκτέλεση της εντολής OUT 25H, AX.

Να σημειώσουμε εδώ ότι η INTEL φυλάσσει τις τελευταίες 16 διευθύνσεις θυρών Ι/Ο
για τα διάφορα περιφερειακά του PC.

2.5 Οι υπόλοιπες εντολές μεταφοράς δεδομένων

Από τις υπόλοιπες εντολές μεταφοράς δεδομένων, οι LAHF και SAHF χρησιμοποιούνται
πολύ σπάνια πλέον (χρησίμευαν για μετάφραση προγραμμάτων του παλιότερου 8085). Η
εντολή XCHG ανταλλάσσει ένα byte ή μια λέξη ανάμεσα στην παράμετρο πηγής και στην
παράμετρο προορισμού π.χ. η XCHG AX, BX θα ανταλλάξει τα περιεχόμενα των ΑΧ και
ΒΧ.

Τέλος η XLAT είναι μια δυνατή εντολή που μετατρέπει το περιεχόμενο του AL σε μια
τιμή που βρίσκει σε έναν πίνακα δεδομένων της μνήμης. Συγκεκριμένα προσθέτει στον ΒΧ
τον AL (η μοναδική εντολή που προσθέτει έναν 8μπιτο με έναν 16μπιτο αριθμό) και το
άθροισμα αυτό θα είναι η απόκλιση (offset) μιας θέσης μνήμης στο data segment. Το
περιεχόμενο της θέσης αυτής θα αντιγραφεί στον AL. Η εντολή αυτή είναι χρήσιμη για
μετατροπή από έναν κώδικα σε άλλον, για παράδειγμα από BCD σε 7-segment κώδικα για
αναπαράσταση σε οθόνες LCD.
39

Στην συνέχεια θα δώσουμε ένα μικρό πρόγραμμα που κάνει την μετατροπή του περιεχομένου
του AL (αν υποθέσουμε ότι είναι ένας αριθμός από το 0 έως το 9) σε κώδικα 7-segment με
χρήση της XLAT. Την δομή του προγράμματος θα την καταλάβετε πλήρως αφού διαβάσετε
και το επόμενο κεφάλαιο. Σημασία έχει εδώ να δούμε πώς αντιστοιχίζεται το περιεχόμενο
του ΑL στην αναπαράστασή του σε 7- segment.

.MODEL SMALL
.DATA

TABLE DB 3FH, 6, 5BH, 4FH


DB 66H, 6DH, 7DH, 27H DB
7FH, 6FH

.CODE

LEA BX, TABLE


XLAT

DOS_EXIT:
MOV AH,4CH MOV
AL,0
INT 21H END
40

Τέλος η CBW (μετατροπή byte σε λέξη) αντιγράφει το bit προσήμου του AL σε όλα τα bits
του ΑΗ, ενώ η CWD (μετατροπή word σε doubleword) αντιγράφει το bit προσήμου του ΑΧ
σε όλα τα bit του DX.

3 Αριθμητικές και λογικές εντολές

Οι αριθμητικές πράξεις που εκτελεί η CPU είναι πρόσθεση, αφαίρεση, πολλαπλασιασμός και
διαίρεση ακεραίων (προσημασμένων ή μη). Αναλυτικά σε κάθε πράξη ανήκουν οι εξής
εντολές :

Πρόσθεση :
ADD, ADC, INC, AAA, DAA

Αφαίρεση :
SUB, SBB, DEC, NEG, CMP, AAS, DAS

Πολλαπλασιασμός :
MUL, IMUL, AAM

Διαίρεση :
DIV, IDIV, AAD

Οι εντολές αυτές περιγράφονται αναλυτικά στο Παράρτημα Α και είναι μάλλον περιττή
περαιτέρω εξήγηση. Τα ακόλουθα εξάλλου παραδείγματα διευκρινίζουν την λειτουργία
των σημαντικότερων από αυτές.

Παραδείγματα :

ADC AX, BX AX = AX + BX + C (carry flag)


ADD AL, [BP] Το byte που βρίσκεται στην διεύθυνση SS:BP προστίθεται
στον AL και το αποτέλεσμα αποθηκεύεται στον AL.
ADD [BX+DI], AH To byte που βρίσκεται στην διεύθυνση με segment τον DS
και offset το ΒΧ+DI προστίθεται με το περιεχόμενο του ΑΗ
και το άθροισμα αποθηκεύεται στην ίδια θέση μνήμης.
ADD BYTE PTR [DI], 5 Το περιεχόμενο της θέσης μνήμης DS:DI που δηλώνεται εδώ
σαν byte αυξάνει κατά 5.
INC DATA1 Το περιεχόμενο της θέσης μνήμης DATA1 (του data
segment) αυξάνεται κατά 1.
41

SUB AX, TEMP Από τον ΑΧ αφαιρείται το περιεχόμενο (λέξη) της


διεύθυνσης TEMP του data segment.
DEC WORD PTR [BP] Το περιεχόμενο της διεύθυνσης SS:BP (δηλώνεται εδώ ως
λέξη) μειώνεται κατά 1.
CMP BX, LIST[DI] Η λέξη που βρίσκεται στην διεύθυνση DS:[LIST+DI]
αφαιρείται από τον ΒΧ και το αποτέλεσμα της αφαίρεσης
δεν καταχωρείται πουθενά. Η πράξη επηρεάζει μόνο τα
flags.
MUL BH Ο ΒΗ πολλαπλασιάζεται με τον AL και το αποτέλεσμα
καταχωρείται στον ΑΧ.
MUL CX Ο ΑΧ πολλαπλασιάζεται με τον CX και το αποτέλεσμα
καταχωρείται στους DS, AX.
DIV SI Ο 32μπιτος μη προσημασμένος αριθμός που βρίσκεται
στους DX, AX διαιρείται με τον SI, το πηλίκο καταχωρείται
στον ΑΧ και το υπόλοιπο στον DX.
NEG AX Υπολογίζεται το συμπλήρωμα ως προς 2 του ΑΧ και το
αποτέλεσμα καταχωρείται στον ΑΧ.

Να προσθέσουμε ότι οι εντολές INC και DEC εν αντιθέσει με τις υπόλοιπες


αριθμητικές, δεν επηρεάζουν τα flags.

Οι λογικές εντολές είναι οι εξής :


NOT, AND, OR, XOR, TEST

Οι εντολές αυτές εκτελούν τις αντίστοιχες λογικές πράξεις σε κάθε ένα από τα bit της
παραμέτρου (βλ. Παράρτημα Α).

Παραδείγματα :

AND BX, [DI] Το κάθε bit του ΒΧ γίνεται λογικό AND με το


αντίστοιχης τάξης bit του περιεχομένου (word) της θέσης μνήμης
DS:DI
OR SP, 10 Το κάθε ένα από τα bit του SP γίνεται λογικό OR με τα
αντίστοιχης τάξης bit της λέξης 000ΑΗ.
XOR AX, 00FFH Ο ΑΗ παραμένει ως έχει, ενώ ο AL αντιστρέφεται, δηλ. γίνεται
το συμπλήρωμα ως προς 1 του AL. Για να καταλάβετε πώς
συμβαίνει αυτό, θυμηθείτε τον πίνακα αληθείας της XOR.
TEST AL, 1 Ο AL γίνεται λογικό AND με το 01Η, αλλά το
αποτέλεσμα της πράξης αυτής δεν καταχωρείται πουθενά.
Επηρεάζονται μόνο τα flags. Στο συγκεκριμένο
παράδειγμα μπορούμε να ελέγξουμε την τιμή του
42

λιγότερο σημαντικού bit (LSB) του AL. Πράγματι, αν αυτό


είναι 1 τότε το zero flag Z = 0, αλλιώς Ζ = 1.
ΝΟΤ ΒΗ Υπολογίζεται το συμπλήρωμα ως προς 1 του ΒΗ και το
αποτέλεσμα καταχωρείται στον ΒΗ.

Εδώ πρέπει να σημειώσουμε ότι τόσο οι αριθμητικές όσο και οι λογικές εντολές δεν μπορούν
να δράσουν πάνω σε segment registers, καθώς και ότι δεν μπορούν επίσης και οι δυο
παράμετροι να είναι τελεστές μνήμης.

4. Εντολές ολίσθησης και περιστροφής

Οι εντολές ολίσθησης και περιστροφής (shift and rotate) διαχειρίζονται δυαδικούς αριθμούς
σε επίπεδο bit όπως και οι λογικές εντολές. Χρησιμοποιούνται συνήθως σε low-level
software για έλεγχο των συσκευών Ι/Ο. Παρέχεται πλήρες σετ που μπορεί να ολισθήσει ή
να περιστρέψει δεξιά ή αριστερά το περιεχόμενο οποιουδήποτε καταχωρητή ή θέσης μνήμης
(εκτός των segment registers).

Οι εντολές αυτές είναι οι εξής (περιγράφονται αναλυτικά στο Παράρτημα Α) :

Ολισθήσεις :
SHL, SAL, SHR, SAR
Περιστροφές :
ROL, ROR, RCL, RCR

Όπως παρατηρούμε, υπάρχουν δύο δεξιές και δύο αριστερές ολισθήσεις. Οι λογικές
ολισθήσεις (SHL, SHR) χρησιμοποιούνται με μη προσημασμένους αριθμούς, ενώ οι
αριθμητικές ολισθήσεις (SAL, SAR), χρησιμοποιούνται με προσημασμένους αριθμούς. Η
λειτουργία τους φαίνεται στο σχ. 3. Οι εντολές SHL και SAL έχουν ακριβώς την ίδια
λειτουργία.
43

Σχήμα 3 Οι εντολές ολίσθησης.

Η λειτουργία των εντολών περιστροφής φαίνεται στο Σχ. 4.

Σχήμα 4 Οι εντολές περιστροφής

Τόσο οι εντολές ολίσθησης όσο και οι εντολές περιστροφής μπορούν να επαναληφθούν τόσες
φορές όσο το περιεχόμενο του μετρητή CL. Το περιεχόμενο του CL είναι εκφρασμένο σε
modulo 32, δηλαδή ο αριθμός που περιέχει ο CL διαιρείται με το 32 και το υπόλοιπο της
44

διαίρεσης δείχνει τον αριθμό των ολισθήσεων ή περιστροφών.

Παράδειγμα :

MOV CL, 34
SHL BH, CL

Οι παραπάνω εντολές προκαλούν την αριστερή ολίσθηση του περιεχομένου του ΒΗ


κατά 2 θέσεις (34/32 αφήνει υπόλοιπο 2).

5 Εντολές χειρισμού αλφαριθμητικών (strings)

Στον 8086 υπάρχει ένα πολύ δυνατό σετ εντολών χειρισμού αλφαριθμητικών (strings) με τις
οποίες μπορούμε να χειριστούμε με ευκολία μεγάλα μπλοκ δεδομένων. Οι εντολές αυτές
μπορούν να χωριστούν σε τρεις υποομάδες, τις εντολές μεταφοράς μπλοκ δεδομένων LODS,
STOS και MOVS, τις εντολές εύρεσης CMPS και SCAS και τις εντολές επανάληψης REP,
REPE/REPZ και RENE/REPNZ.

5.1 Οι εντολές επανάληψης

Οι εντολές επανάληψης επαναλαμβάνουν μια εντολή χειρισμού αλφαριθμητικών τόσες


φορές όσο το περιεχόμενο του καταχωρητή CX. Σε κάθε επανάληψη ο CX μειώνεται κατά 1
μέχρι να μηδενιστεί.. Η REP λειτουργεί χωρίς συνθήκη και χρησιμοποιείται με τις
εντολές MOVS και STOS, ενώ οι REPE/REPZ, REPNE/REPNZ, επαναλαμβάνουν
την αντίστοιχη εντολή μόνον εφόσον το Ζ flag είναι 1 ή 0 αντίστοιχα και χρησιμοποιούνται
με τις εντολές CMPS και SCAS (βλ. και Παράρτημα Α).

5.2 Εντολές μεταφοράς μπλοκ δεδομένων

Στις εντολές αυτές χρησιμοποιούνται οι καταχωρητές SI (Source Index) και DI (Destination


Index), ο πρώτος σαν offset διευθύνσεων του data segment (DS) και ο δεύτερος για το extra
segment (ES). Μετά την εκτέλεση κάθε εντολής, οι δείκτες αυτοί αυξάνονται ή
μειώνονται, ανάλογα με την τιμή του D flag (direction). Αν D=0,
οι δείκτες αυξάνονται ενώ αν D=1 οι δείκτες μειώνονται.

Οι εντολές MOVS, LODS και STOS περιγράφονται αναλυτικά στο Παράρτημα Α.


Συνοπτικά λειτουργούν ως εξής :
45

LODS,LODSB,LODSW Το περιεχόμενο της DS:SI αντιγράφεται στον AL


(LODSB) ή στον ΑΧ (LODSW) και ο SI αυξάνεται αν D=0
(ή μειώνεται αν D=1) κατά 1 ή 2 αντίστοιχα. Η LODS
χρειάζεται και σαν παράμετρο έναν τελεστή μνήμης, το
μέγεθος του οποίου καθορίζει αν θα έχουμε μεταφορά byte ή
word.
STOS, STOSB, STOSW Λειτουργεί ακριβώς αντίστροφα από την LODS, δηλ. ο
AL (ή ο ΑΧ) αντιγράφεται στην ES:[DI].
MOVS,MOVSB,MOVSW Ένα byte (MOVSB) ή word (MOVSW) αντιγράφεται
από την θέση μνήμης DS:SI στην ES:DI. Οι δείκτες SI, DI
αυξάνονται (ή μειώνονται) κατά 1 ή 2 αντίστοιχα.

Παραδείγματα :
LODSW AXÅDS:[SI] , SIÅSI±2
LODS DATA1 ALÅDS:[SI], SIÅSI±1 αν DATA1 είναι byte ή
AXÅDS:[SI], SIÅSI±2 αν DATA1 είναι word.
STOSB ES:[DI]ÅAL, DIÅDI±1
MOVSW ES:[DI]ÅDS:[SI], DIÅDI±2, SIÅSI±2 (μεταφορά λέξης). REP
MOVSB Η εντολή MOVSB εκτελείται τόσες φορές όσο το περιεχόμενο
του CX, o CX καθορίζει δηλαδή το μέγεθος του μπλοκ μνήμης που
θα μεταφερθεί από το data στο extra segment.

Έστω ότι θέλουμε να μεταφέρουμε το μπλοκ μνήμης από 0500:0100 έως 0500:0300 στις
θέσεις μνήμης Α000:0000 έως Α000:0200. Το μήκος του μπλοκ είναι 200Η bytes. Το
παρακάτω τμήμα προγράμματος κάνει αυτή την εργασία.

MOV AX, 0500H MOV


DS, AX
MOV AX, AOOOH
MOV ES, AX MOV
SI, 100H MOV DI,
0
MOV CX, 200H

CLD
REP MOVSB

Όπου η εντολή CLD θέτει D=0.


46

5.3 Εντολές εύρεσης και σύγκρισης string

Οι εντολές αυτές είναι οι SCAS και CMPS. Αναλυτικότερα :

Η εντολή SCAS (scan string) συγκρίνει το byte (SCASB) ή το word (SCASW) που βρίσκεται
στην διεύθυνση ES:DI με τον AL ή τον ΑΧ αντίστοιχα. Η σύγκριση επηρεάζει μόνο τα flags.
Σε συνδυασμό με την REPNE (ή την όμοια REPNZ) μπορεί να χρησιμοποιηθεί για να βρει
ένα byte ή μια λέξη κλειδί σε ένα μπλοκ μνήμης. Το επόμενο πρόγραμμα ψάχνει στο μπλοκ
που αρχίζει από την διεύθυνση 0100:0Α00 και έχει μήκος 1 Kbyte για να βρει το byte BBH.

MOV AX, 0100H MOV


ES, AX
MOV DI, 0A00H
MOV CX, 1024
MOV AL, 0BBH
REPNE SCASB

Η εντολή αυτή μπορεί επίσης να χρησιμοποιηθεί με την REPE (ή την όμοια REPZ), σε
ρουτίνες παράκαμψης επαναλαμβανόμενου byte ή word. Το κομμάτι προγράμματος που
ακολουθεί παρακάμπτει (πηδά) τον χαρακτήρα ΄΄κενό΄΄ (ASCII
20H) σε κάποιο string που ξεκινά από την διεύθυνση ES:DI.

CLD
MOV CX, 0FFFFH MOV
AL, 20H REPE SCASB

Στην παραπάνω ρουτίνα (που μπορεί να χρησιμοποιηθεί σε προγράμματα συμπίεσης


δεδομένων), η εντολή SCASB επαναλαμβάνεται όσο βρίσκουμε τον χαρακτήρα
‘space’ (20H) βαδίζοντας έτσι μέσα στο string μέχρι να βρεθεί ένας χαρακτήρας
διαφορετικός.

Η εντολή CMPS συγκρίνει τα περιεχόμενα της διεύθυνσης ES:DI με αυτά της


διεύθυνσης DS:SI, που μπορεί να είναι bytes (CMPSB) ή words (CMPSW). Σε
συνδυασμό με την REPE μπορεί να συγκρίνει δυο μπλοκ μνήμης αν έχουν τα ίδια
περιεχόμενα. Το επόμενο πρόγραμμα συγκρίνει το μπλοκ μνήμης που αρχίζει στην
διεύθυνση Α000:0100 με αυτό που αρχίζει στην Β000:3E00. Και τα δυο μπλοκ έχουν
μήκος 100 bytes.

MOV AX, 0A000H MOV


47

ES, AX
MOV AX, 0BOOOH MOV
DS, AX
MOV DI, 100H
MOV SI, 3E00H CLD
MOV CX, 100
REPE CMPSB

Αν τα δυο μπλοκ είναι ίδια, στο τέλος του προγράμματος ο CX θα έχει μηδενιστεί και το zero
flag θα είναι 1. Σε αντίθετη περίπτωση, δηλ. αν είτε CX>0 είτε Ζ=0, τα δυο μπλοκ δεν θα
έχουν ακριβώς το ίδιο περιεχόμενο.

6. Εντολές χειρισμού των flags

Οι εντολές αυτές είναι οι CLC, STC, CLD, STD, CLI, STI και CMC. Η λειτουργία τους
έχει ως εξής :

CLC Clear carry flag (C=0) STC


Set carry flag (C=1)
CLD Clear direction flag (D=0) STD
Set direction flag (D=1) CLI
Clear interrupt flag (I=0) STI
Set interrupt flag (I=1)
CMC Complement carry flag – To carry flag αλλάζει τιμή.

7. Εντολές ελέγχου προγράμματος

Οι εντολές ελέγχου προγράμματος είναι οι εξής :

CALL Κλήση υπορουτίνας.


RET Επιστροφή από υπορουτίνα.
48

JMP Άλμα JA/JNBE/JG/JNLE


Άλμα αν μεγαλύτερο.
JAE/JNB/JGE/JNL Άλμα αν μεγαλύτερο ή ίσο.
JB/JNAE/JL/JNGE Άλμα αν μικρότερο
JBE/JNA/JLE/JNG Άλμα αν μικρότερο ή ίσο
JC Άλμα αν υπάρχει κρατούμενο (C=1)
JE/JZ Άλμα αν ίσο (Ζ=1)
JNC Άλμα αν C=0
JNE/JNZ Άλμα αν όχι ίσο (Ζ=0)
JNO Άλμα αν δεν έχουμε υπερχείλιση (Ο=0)
JNP/JPO Άλμα αν έχουμε περιττή ισοτιμία (Ρ=0) JNS
Άλμα αν δεν υπάρχει πρόσημο (S=0)
JO Άλμα αν έχουμε υπερχείλιση (Ο=1).
JP/JPE Άλμα αν έχουμε άρτια ισοτιμία (Ρ=1) JS
Άλμα αν S=1.
LOOP Επανάληψη χωρίς συνθήκη
LOOPE/LOOPZ Επανάληψη αν ίσο (Ζ=1)
LOOPNE/LOOPNZ Επανάληψη αν όχι ίσο (Ζ=0) JCXZ
Άλμα αν ο καταχωρητής CX=0
INT Διακοπή
INTΟ Διακοπή σε υπερχείλιση
IRET Επιστροφή από διακοπή.

7.1 Οι εντολές JMP

Με χρήση της εντολής JMP (jump) μπορούμε να μεταβούμε σε όποιο σημείο του
προγράμματος θέλουμε. Η εντολή αυτή υπάρχει σε τρεις εκδοχές : short jump, near jump και
far jump.

Tα short jumps επιτρέπουν διακλαδώσεις από –128 έως +127 θέσεις μνήμης από την θέση
της επόμενης εντολής που πρόκειται να εκτελεστεί. Η αντίστοιχη εντολή έχει μέγεθος 2
bytes, ένα για τον λειτουργικό κώδικα της εντολής (opcode) και ένα για την τιμή της
μετατόπισης (displacement) που είναι προσημασμένος 8μπιτος αριθμός. Ο αριθμός αυτός
προστίθεται στην τιμή του ΙΡ, έτσι ώστε να προκύψει η διεύθυνση διακλάδωσης.

Τα near jumps επιτρέπουν διακλαδώσεις μέχρι ±32Κ θέσεις μνήμης από την διεύθυνση της
επόμενης προς εκτέλεση εντολής. Έτσι μπορούν να προσπελάσουν οποιαδήποτε διεύθυνση
στο τρέχον segment (μεγέθους 64Κ). Αυτό συμβαίνει επειδή
49

τα segments είναι κυκλικά, δηλαδή αν η επόμενη προς εκτέλεση εντολή είναι στην θέση
με offset 0004H και εμείς θέλουμε να μεταβούμε στην θέση FFFFH, αρκεί να δώσουμε
ως displacement το –5. Το near jump έχει μέγεθος 3 bytes, ένα για τον opcode και δύο
για το displacement. To displacement είναι προσημασμένος 16μπιτος αριθμός που
προστίθεται στον ΙΡ για να προκύψει η διεύθυνση διακλάδωσης.

Τόσο τα short όσο και τα near jumps ονομάζονται και σχετικά (relatives), διότι τα
προγράμματα που τα χρησιμοποιούν μπορούν να επανατοποθετηθούν σε άλλο σημείο της
μνήμης χωρίς αλλαγές στον κώδικα. Αυτό συμβαίνει διότι δεν δίνουμε άμεσα τιμή
στον ΙΡ, αλλά μετατόπιση από την τρέχουσα τιμή του, όποια και αν είναι αυτή.

Τα far jumps επιτρέπουν διακλαδώσεις σε οποιοδήποτε σημείο της μνήμης. Η εντολή


αυτή έχει μήκος 5 bytes, ένα για τον opcode, δύο για την νέα τιμή του ΙΡ και δύο για την
νέα τιμή του CS. Κάθε φορά που το πρόγραμμα που χρησιμοποιεί far jumps
επανατοποθετείται στην μνήμη, ο κώδικας μηχανής της εντολής αλλάζει. Στο σχ. 5
φαίνονται οι τρεις αυτοί τύποι της εντολής JMP.

short jump EB Disp

near jump Disp. High


E9 Disp. Low
far jump EA IP Low IP High CS Low CS High

Σχήμα 5 Οι τρεις τύποι της εντολής JMP.

Ο προγραμματιστής δεν χρειάζεται συνήθως να δηλώνει τι τύπο εντολής JMP θα


χρησιμοποιεί, διότι την εργασία αυτή την κάνει ο assembler. Για far jumps η διεύθυνση
μετάβασης πρέπει να δηλώνεται ως far.

Εκτός της εντολής JMP που είναι εντολή διακλάδωσης χωρίς συνθήκη, υπάρχουν και οι
εντολές διακλάδωσης υπό συνθήκη που προαναφέρθηκαν. Αυτές όμως κάνουν μόνo
short jumps (-128 έως +127 θέσεις).

Παράδειγμα :

Το επόμενο πρόγραμμα βρίσκει τον μικρότερο από τρεις αριθμούς και τον τοποθετεί στον
DL. Οι τρεις αριθμοί βρίσκονται αρχικά στους AL, BL, CL.
50

MOV DL, AL ;Έστω ότι ο AL μικρότερος


CMP DL, BL ;Αν DL <= BL τότε
JBE L1 ; πήγαινε στην θέση L1
MOV DL, BL ; αλλιώς βάλε τον BL στον DL L1:
CMP DL, CL ;Αν DL <= CL τότε
JBE EXIT ; πήγαινε στην θέση EXIT MOV
DL, CL ; αλλιώς βάλε τον CL στον DL
EXIT:

Τέλος υπάρχει η δυνατότητα για indirect jumps, δηλαδή για χρήση καταχωρητών ή τελεστών
μνήμης για την εύρεση της διεύθυνσης μετάβασης. Το περιεχόμενο του καταχωρητή ή της
θέσης μνήμης θα τοποθετηθεί στον ΙΡ. Θεωρούμε πάντα ότι έχουμε near jumps, εκτός
αν βάλουμε το directive FAR PTR.

Παραδείγματα :

JMP AX Άλμα στην διεύθυνση CS:AX (IP Å AX)


JMP ADDR1 Το περιεχόμενο της διεύθυνσης ADDR1 του data segment
τίθεται ως νέο περιεχόμενο του
51

JMP FAR PTR [SI] Ο ΙΡ θα πάρει ως νέα τιμή το περιεχόμενο των διευθύνσεων DS:[SI],
DS:[SI+1] και ο CS το DS:[SI+2], DS:[SI+3]. Έτσι θα προκύψει μια
νέα διεύθυνση σε άλλο segment (far address).

7.2 Οι εντολές LOOP

Η εντολή LOOP (επανάληψη χωρίς συνθήκη) είναι ένας συνδυασμός των εντολών DEC CX
και JNZ, δηλαδή μειώνει την τιμή του CX (μετρητής επαναλήψεων) κατά 1, και αν αυτός δεν
έχει γίνει 0, μεταπηδά στην διεύθυνση που δίνεται σαν παράμετρος. Η διεύθυνση βέβαια αυτή
δεν μπορεί να είναι μακρύτερα από –128 έως +127 θέσεις από την θέση της επόμενης προς
εκτέλεση εντολής.

Εκτός της LOOP υπάρχουν και οι εντολές επανάληψης υπό συνθήκη που προαναφέρθηκαν.

Παράδειγμα :

Το επόμενο πρόγραμμα ψάχνει μέσα σε μια σειρά δεδομένων (ARRAY1) μήκους 100
λέξεων μέχρι να βρει την πρώτη μη μηδενική λέξη. Η εντολή CMP WORD PTR [AX],
0 συγκρίνει το περιεχόμενο κάθε λέξης με το 0, και όσο αυτά είναι ίσα το Ζ=1,
άρα ο βρόγχος επαναλαμβάνεται.

LEA AX, ARRAY1


SUB AX, 2
MOV CX, 100
L1: ADD AX, 2
CMP WORD PTR [AX], 0
LOOPZ L1

7.3 Οι εντολές CALL και RET

Οι υπορουτίνες (procedures ή subroutines) είναι ένα σύνολο εντολών που εκτελούν κάποια
συγκεκριμένη εργασία. Ενώ γράφονται μόνο μια φορά, μπορούν να προσπελαστούν πολλές
φορές στην διάρκεια εκτέλεσης ενός προγράμματος. Η ύπαρξη υπορουτινών, πέρα από
την προφανή μείωση του όγκου ενός προγράμματος, δίνει την δυνατότητα δημιουργίας
βιβλιοθηκών που θα χρησιμοποιούνται από όλα τα προγράμματα του χρήστη. Το μόνο
μειονέκτημα είναι ο χρόνος μετάβασης και επιστροφής στο κυρίως πρόγραμμα.

Κάθε υπορουτίνα (procedure) έχει ένα όνομα με το οποίο καλείται από την εντολή CALL
52

και τελειώνει πάντα με την εντολή RET, η οποία επιστρέφει τον έλεγχο στην επόμενη εντολή
από την κλήση της υπορουτίνας.

Ένα παράδειγμα υπορουτίνας είναι το ακόλουθο :

EQU1 PROC NEAR ADD

AX, AX
ADC AX, BX RET

EQU1 ENDP

Η υπορουτίνα αυτή υπολογίζει την παράσταση 2*ΑΧ+ΒΧ και καταχωρεί το αποτέλεσμα


στον ΑΧ. EQU1 είναι το όνομα της υπορουτίνας, PROC είναι το directive που δείχνει
ότι πρόκειται για procedure, NEAR σημαίνει ότι μπορεί να κληθεί μόνο μέσα από το ίδιο
segment και τέλος το directive ENDP (end of procedure) δείχνει το τέλος της υπορουτίνας.

Η εντολή CALL όπως προαναφέρθηκε, κάνει ένα άλμα στην διεύθυνση της υπορουτίνας το
όνομα της οποίας δίνεται σαν παράμετρος. Πριν όμως από αυτό, και αυτή είναι η διαφορά
της με την εντολή JMP, σώζει στον σωρό την διεύθυνση της επόμενης προς εκτέλεση
εντολής, έτσι ώστε να μπορέσει αργότερα να επιστρέψει στο σωστό σημείο του κυρίως
προγράμματος.

Η εντολή CALL μπορεί να είναι near (κλήση υπορουτίνας που βρίσκεται στο ίδιο
segment), οπότε σώζεται στον σωρό μόνο ο ΙΡ, ή far (κλήση υπορουτίνας που βρίσκεται σε
άλλο segment), οπότε σώζονται τόσο ο ΙΡ όσο και ο CS. Επίσης, όμοια με την εντολή JMP,
μπορούμε να χρησιμοποιήσουμε σαν παράμετρο κάποιον καταχωρητή ή τελεστή μνήμης, το
περιεχόμενο των οποίων θα μας δίνει την διεύθυνση της υπορουτίνας που θέλουμε να
καλέσουμε.

Η εντολή RET αν βρίσκεται μέσα σε υπορουτίνα που έχει δηλωθεί σαν near επαναφέρει από
τον σωρό το περιεχόμενο του ΙΡ, ενώ αν η υπορουτίνα έχει δηλωθεί σαν far, επαναφέρονται
τόσο ο ΙΡ όσο και ο CS.

7.4 Εντολές διακοπών

Οι εντολές ΙΝΤ, ΙΝΤΟ και IRET περιγράφονται στο κεφάλαιο για τις διακοπές. Εδώ θα
παρατηρήσουμε μόνο ότι η εντολή ΙΝΤ είναι παρόμοια με μια εντολή far CALL στην
διεύθυνση της ρουτίνας εξυπηρέτησης της διακοπής. Τα πλεονεκτήματα όμως της χρήσης
53

της ΙΝΤ είναι τα εξής :

1. Η ΙΝΤ έχει σαν παράμετρο μόνο έναν 8μπιτο αριθμό (τον τύπο της διακοπής) ενώ η far
CALL έχει σαν παράμετρο 4 byte (segment και offset της διεύθυνσης της υπορουτίνας).
Έτσι, η εντολή ΙΝΤ έχει μέγεθος μόνο δύο byte ενώ η far CALL έχει μέγεθος 5 byte,
κάτι που σημαίνει ότι κερδίζουμε σημαντικά σε μέγεθος και ταχύτητα προγράμματος, αν
λάβουμε μάλιστα υπ΄όψη την συχνότητα χρήσης της ΙΝΤ.
2. Η εντολή ΙΝΤ σώζει αυτόματα και τον flag register (F), κάτι που διαφορετικά θα έπρεπε
να γίνεται σε όλες τις ρουτίνες εξυπηρέτησης διακοπών.
3. Επιτρέπεται η λειτουργία των προγραμμάτων ανεξάρτητα συστήματος. Ο
προγραμματιστής δηλαδή δεν χρειάζεται να γνωρίζει τις διευθύνσεις στην μνήμη των
ρουτινών του συστήματος, κάτι άλλωστε που αλλάζει από κατασκευαστή σε
κατασκευαστή. Αυτό είναι και το σημαντικότερο πλεονέκτημα, διότι έτσι ένα πρόγραμμα
assembly μπορεί να εκτελείται σε όλα τα PC.

8 Εντολές ελέγχου του επεξεργαστή

Οι εντολές αυτές είναι :

HLT Ο επεξεργαστής σταματά να εκτελεί εντολές μέχρι να γίνει


κάποια διακοπή (HALT).
WAIT Αναμονή μέχρι την ενεργοποίηση του ακροδέκτη TEST.
ESC ESCAPE σε εξωτερικό επεξεργαστή.
LOCK Κλείδωμα του διαύλου κατά την διάρκεια της επόμενης
εντολής.
NOP Η εντολή αυτή δεν κάνει τίποτα. Μπορεί να χρησιμοποιηθεί για
χρονική καθυστέρηση.
54

ΠΑΡΑΡΤΗΜΑ Β

ΠΕΡΙΒΑΛΛΟΝ ΕΞΟΜΟΙΩΣΗΣ EMU8086


Το περιβάλλον εξομοίωσης emu8086 είναι ένα ολοκληρωμένο περιβάλλον ανάπτυξης
προγραμμάτων σε συμβολική γλώσσα αρχιτεκτονικής 8086 με δυνατότητες ελέγχου
σφαλμάτων, εξομοίωσης της εκτέλεσης του προγράμματος του χρήστη αλλά και
συμβολομετάφραση του κώδικα και δημιουργία εκτελέσιμων προγραμμάτων (.EXE,.COM).
Το περιβάλλον επιτρέπει την εκτέλεση κώδικα σε βήματα και τη δυνατότητα εισαγωγής
σημείων παύσης της εκτέλεσης του προγράμματος (Breakpoints) για την ταχύτερη αναγνώριση
σημείων σφάλματος.

ΕΚΚΙΝΗΣΗ ΠΕΡΙΒΑΛΛΟΝΤΟΣ EMU 8086


Κατά την εκκίνηση του προγράμματος εμφανίζεται το παράθυρο επιλογών που απεικονίζεται
στο παρακάτω σχήμα

Λειτουργίες
1. new: Δημιουργία ενός νέου αρχείου προγράμματος
2. code examples: Παραδείγματα εκμάθησης συμβολικής γλώσσας του 8086. Τα
παραδείγματα καλύπτουν ευρύ φάσμα λειτουργιών από απλές έως πολύ σύνθετες
3. quick start tutor: οδηγίες χρήσης του περιβάλλοντος emu8086 (και της συμβολικής γλώσσας
8086)
4. recent files: Λίστα με τα πιο πρόσφατα αρχεία
55

ΔΗΜΙΟΥΡΓΙΑ ΝΕΟΥ ΑΡΧΕΙΟΥ


Επιλέγοντας τη δημιουργία νέου αρχείου προγράμματος εμφανίζεται το παρακάτω παράθυρο
επιλογών το οποίο επιτρέπει τη δημιουργία διαφόρων μορφών προγραμμάτων ανάλογα με τις
ανάγκες του χρήστη μέσα από ένα σύνολο προτύπων

Λειτουργίες
1. COM template: Δημιουργία εκτελέσιμου αρχείου .com
2. EXE template: Δημιουργία εκτελέσιμου αρχείου .exe
3. BIN template: δημιουργία δυαδικού εκτελέσιμου αρχείου για ενσωμάτωση σε μια μνήμη (π.χ.
ROM για απευθείας εκτέλεση από ένα σύστημα χωρίς τη μεσολάβηση λειτουργικού
συστήματος.
4. ΒΟΟΤ template: Αρχείο προγράμματος εκκίνησης ενός συστήματος (δεν απαιτείται η ύπαρξη
λειτουργικού συστήματος)
5. empty workspace: Κενό πρότυπο. Όλα τα τμήματα προγράμματος ορίζονται από τον
προγραμματιστή
6. the emulator: Απευθείας εκτέλεση του εξομοιωτή
56

ΠΕΡΙΒΑΛΛΟΝ ΑΝΑΠΤΥΞΗΣ ΑΡΧΕΙΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ


Επιλέγοντας το πρότυπο δημιουργίας εκτελέσιμου προγράμματος προκύπτει η οθόνη που
απεικονίζεται στο επόμενο σχήμα. Σημειώνεται ότι κάθε εντολή έχει αριστερά αριθμό ο οποίος
χρησιμοποιείται για αναφορά σε αυτή

Λειτουργίες
1. new: Δημιουργία νέου αρχείου προγράμματος (Οδηγεί στον προηγούμενο κατάλογο
επιλογών)
2. open: Άνοιγμα έτοιμου αρχείου προγράμματος
3. save: Αποθήκευση του αρχείου που είναι ανοιχτό στο περιβάλλον ανάπτυξης
4. compile: Έλεγχος σφαλμάτων, συμβολομετάφραση και δημιουργία του αρχείου
προγράμματος όπως περιγράφεται από το πρότυπο που έχουμε διαλέξει (.EXE,.COM,.BIN)
5. emulate: Έλεγχος σφαλμάτων και συμβολομετάφραση για την εκτέλεση του προγράμματος
στον εξομοιωτή
6. calculator: πρόγραμμα εκτέλεσης πράξεων μεταξύ τελεστέων στα 4 βασικά συστήματα
αρίθμησης (Δεκαδικό , Δεκαεξαδικό, Δυαδικό, Οκταδικό)
7. convertor: πρόγραμμα μετατροπής αριθμών μεταξύ των τεσσάρων βασικών συστημάτων
αρίθμησης (Δεκαδικό , Δεκαεξαδικό, Δυαδικό, Οκταδικό)
8. options: Ρυθμίσεις περιβάλλοντος του emu8086
9. help: Οδηγίες χρήσης του emu8086, οδηγίες ανάπτυξης προγραμμάτων στην αρχιτεκτονική
του 8086, κατάλογος εντολών 8086 και διακοπών του 8086.
57

ΣΥΜΒΟΛΟΜΕΤΑΦΡΑΣΗ ΑΡΧΕΙΟΥ ΠΡΟΓΡΑΜΜΑΤΟΣ


Μετά τη συγγραφή ενός αρχείου προγράμματος η επιλογή compile οδηγεί στις επιλογές
αποθήκευσης του αρχείου (στην περίπτωση που απεικονίζεται είχε επιλεγεί αρχικά η λειτουργία
δημιουργίας ενός εκτελέσιμου αρχείου με επέκταση .EXE) εφόσον δεν υπάρχουν συντακτικά λάθη

Η συμβολομετάφραση μπορεί να ολοκληρωθεί με λάθη ή χωρίς λάθη όπως απεικονίζεται στα


σχήματα που ακολουθούν

Συμβολομετάφραση χωρίς λάθη Συμβολομετάφραση με λάθη

Στην παραπάνω περίπτωση η λάθος συμβολομετάφραση οφείλεται στην εντολή με αριθμό 19 του
κώδικα (MOV si,al) όπου εσφαλμένα ένας καταχωρητής 16 bit λαμβάνει την τιμή ενός καταχωρητή 8
bit.
58

ΕΞΟΜΟΙΩΣΗ ΓΙΑ ΤΟΝ ΕΛΕΓΧΟ ΚΑΙ ΤΗ ΔΙΑΔΡΑΣΤΙΚΗ ΕΚΤΕΛΕΣΗ ΠΡΟΓΡΑΜΜΑΤΟΣ


Το περιβάλλον του εξομοιωτή ενεργοποιείται από το περιβάλλον ανάπτυξης του αρχείου
προγράμματος με την εντολή emulate και παρέχει προς χρήση ένα ιδεατό περιβάλλον ενός
υπολογιστή που διαθέτει επεξεργαστή 8086. Η κεντρική οθόνη του εξομοιωτή απεικονίζεται στο
ακόλουθο σχήμα.

1 2 3
Λειτουργίες
Η οθόνη του εξομοιωτή περιέχει τρία βασικά παράθυρα. Το πρώτο παράθυρο περιέχει τις τιμές των
καταχωρητών του 8086 όπως αυτές ενημερώνονται μετά την εκτέλεση κάθε εντολής. Το δεύτερο
παράθυρο περιέχει τις φυσικές διευθύνσεις στη μνήμη και την τιμή που περιέχεται σε κάθε μια από
αυτές (σε δεκαεξαδική και σε δεκαδική τιμή). Οι τιμές που αντιστοιχούν στην επόμενη προς
εκτέλεση εντολή έχουν μπλέ υπόβαθρο. Η αρχή της επόμενης προς εκτέλεση εντολής υπολογίζεται
από το ζευγάρι καταχωρητών CS:IP. Στο τρίτο παράθυρο απεικονίζονται οι εντολές του αρχείου
προγράμματος όπου έχουν αντικατασταθεί οι ετικέτες κάθε είδους με τις τιμές που αντιστοιχούν σε
αυτές, όπως υπολογίστηκαν κατά τη συμβολομετάφραση, ενώ έχουν αντικατασταθεί και όλες οι
μακροεντολές με τον κώδικα που αντιστοιχεί σε αυτές. Η επόμενη προς εκτέλεση εντολή σε αυτό το
παράθυρο έχει επίσης μπλε υπόβαθρο.

1. Load: φωρτώνει ένα αρχείο (.asm,.com,.exe) ώστε να εξομοιώσει τη λειτουργία των εντολών
που περιέχονται
2. reload: Επαναρχικοποιούν τους καταχαρητές στις τιμές που είχαν πριν την εκτέλεση
(εξομοίωση) ενός προγράμματος.
3. step back: αναίρεση της εκτέλεσης της τελευταίας εντολής.
4. single step: Εκτελεί την επόμενη προς εκτέλεση εντολή
5. run: εκτελεί το πρόγραμμα που έχει φορτωθεί στον εξομοιωτή είτε ολόκληρο είτε μέχρι το
σημείο ενός Breakpoint εφόσον έχει οριστεί.
59

6. Κλίμακα step delay: Ορίζει το χρόνο μεταξύ της εκτέλεσης διαδοχικών εντολών.

Εκτός από την κεντρική οθόνη του εξομοιωτή αναπτύσσεται και η οθόνη του παρακάτω σχήματος
η οποία περιέχει το αρχικό αρχείο προγράμματος όπου είναι επισημασμένη η επόμενη προς
εκτέλεση εντολή σε συμφωνία με τη σήμανση στο κεντρικό παράθυρο του εξομοιωτή

Πρόσθετα Παράθυρα Χρήσιμων Πληροφοριών


Η επιλογή flags στο κάτω μέρος του κεντρικού παραθύρου του εξομοιωτή (ή view→flags) οδηγεί στην
οθόνη που ακολουθεί και απεικονίζει την τιμή των σημαιών (αντίστοιχα με το κουμπί analyze
εκπτύσσεται περιγραφή των τιμών της κάθε σημαίας).

Η επιλογή stack στο κάτω μέρος του κεντρικού παραθύρου του εξομοιωτή (ή view→stack) οδηγεί
την παρακάτω οθόνη,
60

Στο παράθυρο αυτό επισημαίνεται η θέση στην οποία βρίσκεται η κορυφή του σωρού με το <.

Η επιλογή debug (view→log and debug.exe emulation) στο κάτω μέρος του κεντρικού παραθύρου
του εξομοιωτή επιστρέφει τις τιμές των καταχωρητών το διάνυσμα κατάστασης του επεξεργαστή
όπως και τις λεπτομέρειες τις επόμενης προς εκτέλεσης εντολής. Ένα χαρακτηριστικό παράδειγμα
απεικονίζεται στο ακόλουθο σχήμα

Η επιλογή vars στο κάτω μέρος του κεντρικού παραθύρου του εξομοιωτή ( ή view→vars) αναπτύσσει
την οθόνη που απεικονίζει το παρακάτω σχήμα

Στην οθόνη αυτή περιέχονται οι μεταβλητές που είναι ορισμένες στο πρόγραμμα το μέγεθος που
καταλαμβάνει κάθε τιμή αυτής (byte,word) καθώς και το πόσα στοιχεία έχει η κάθε μεταβλητή και
το αριθμητικό σύστημα που επιθυμούμε να απεικονιστεί.

Με την επιλογή aux→memory (view→memory) μπορεί να απεικονιστεί ένα τμήμα 128 byte της
μνήμης όπως φαίνεται στο ακόλουθο σχήμα για το οποίο μπορούμε να ορίσουμε τη διεύθυνση
61

αρχής αλλά και να γράψουμε απευθείας νέες τιμές στις διάφορες θέσεις. Η αλλαγή περιεχομένων
της μνήμης μπορεί να γίνει είτε αλλάζοντας τη δεκαεξαδική αναπαράσταση είτε την ASCII.
62

ΠΑΡΑΡΤΗΜΑ Γ

Σετ εντολών του 8086

Στην συνέχεια παραθέτονται αναλυτικά όλες οι εντολές του 8086, με την σύνταξη της
καθεμιάς, σύντομη εξήγηση λειτουργίας και επίδρασή της επί των διαφόρων flags. Επίσης
αναφέρονται οι χρόνοι εκτέλεσης της κάθε εντολής σε περιόδους ρολογιού (Τ).

Στους χρόνους αυτούς προστίθεται ορισμένες φορές το ea (Effective Address), που είναι
ο χρόνος υπολογισμού της φυσικής διεύθυνσης ενός τελεστή μνήμης. Οι χρόνοι αυτοί
διαφέρουν ανάλογα με τον τύπο του τελεστή μνήμης και φαίνονται αναλυτικά στον Πίνακα
Α.1. Αυτοί οι χρόνοι αφορούν υπολογισμούς για το εξ ορισμού segment. Όταν
καθορίζουμε διαφορετικό segment από το εξ ορισμού (segment override), για παράδειγμα
στην εντολή MOV DL, ES:[AX], πρέπει σε αυτούς τους χρόνους να
προσθέσουμε άλλα 2Τ.

Τύπος Χρόνος ea Παράδειγμα εντολής


Μετατόπιση – offset 3T MOV AH, LIST1
Βάση ή δείκτης 5T MOV AL,[DI]
Βάση + δείκτης 7T MOV CL, [BP+SI]
Βάση (ή δείκτης) + μετατόπιση 9Τ MOV BH, [SI+0AH]
Βάση + δείκτης + μετατόπιση 11Τ MOV AH, [BX+SI+6]

Πίνακας Α.1 Χρόνος υπολογισμού effective address.

Χρησιμοποιούμε τα εξής σύμβολα για τα flags:

1 Το αντίστοιχο flag γίνεται 1


0 Το αντίστοιχο flag γίνεται 0
? Μη προκαθορισμένη επίδραση
* Η εντολή επιδρά στο flag με τρόπο που έχει σχέση με την λειτουργία της.

Αν το κουτάκι ενός flag είναι κενό, σημαίνει ότι η εντολή δεν επιδρά στο αντίστοιχο
flag.

Για την σύντομη παρουσίαση της σύνταξης της κάθε εντολής, χρησιμοποιούμε τον
εξής συμβολισμό: ΕΝΤΟΛΗ dest, source, όπου το όνομα της εντολής μπορεί να
63

ακολουθείται από 1 ή 2 παραμέτρους. Η πρώτη ονομάζεται παράμετρος προορισμού (dest)


και η δεύτερη παράμετρος πηγής (source). Οι παράμετροι αυτοί μπορεί να είναι κάτι από τα
εξής:

reg Ένας εκ των καταχωρητών: AX, BX, CX, DX, AH, AL, BH, BL, CH,
CL, DH, DL, SI, DI, BP ή SP.
seg Ένας καταχωρητής segment (CS, DS, SS, ES). acc
Συσσωρευτής (ΑΧ ή AL).
mem Ένας τελεστής μνήμης (πχ. day1, ES:[DI], [1234], [ΒΧ + 0ΑΗ] κτλ.
shortlabel Μια τοποθεσία –128 έως +127 bytes από την επόμενη εντολή. nearlabel
Μια τοποθεσία μέσα στο ίδιο segment.
farlabel Μια τοποθεσία σε διαφορετικό segment. imm
Μια άμεσα διδόμενη τιμή (πχ. 29).

AAA ASCII adjust after addition (8Τ) O D

I T S Z A P C
? ? ? * ? *

Διορθώνει το αποτέλεσμα στον AL , μετά την πρόσθεση δύο ASCII ψηφίων. Οι δεκαδικοί
αριθμοί (0-9) στον ASCII κώδικα καταλαμβάνουν τους κωδικούς από 30Η έως 39H,
επομένως μια απευθείας πρόσθεση οδηγεί σε λάθος αποτέλεσμα.

AAD ASCII adjust before division (60Τ) O

D I T S Z A P C
? * * ? * ?

Ρύθμιση ASCII για διαίρεση. Προηγείται της εντολής DIV.

AAM ASCII adjust after multiply (83Τ) O

D I T S Z A P C
? * * ? * ?

Ρύθμιση του γινομένου ASCII ψηφίων στον ΑΧ.


64

AAS ASCII adjust after subtraction (8Τ)

O D I T S Z A P C
? ? ? * ? *

Ρύθμιση ASCII μετά από αφαίρεση

ADC Add with carry

O D I T S Z A P C
* * * * * *

Σύνταξη:
ADC reg, reg (3Τ) ADC reg, mem (9Τ+ea) ADC
reg, imm (4Τ) ADC mem, reg (16+ea) ADC mem,
imm (17+ea)

Πρόσθεση της παραμέτρου προορισμού, πηγής και carry flag. Το άθροισμα


αποθηκεύεται στην παράμετρο προορισμού.

Παραδείγματα:

ADC BX, 4 BX Å BX + 4 + C ADC


DI , data1
ADC [SI], 45
ADC AH, L1[BX]

ADD Addition

O D I T S Z A P C
* * * * * *

Πρόσθεση της παραμέτρου πηγής στην παράμετρο προορισμού και αποθήκευση του
αθροίσματος στην παράμετρο προορισμού.

Σύνταξη:
ADD reg, reg (3T) ADD reg, mem (9T+ea)
65

ADD reg, imm (4T) ADD mem, reg (16T+ea) ADD


mem, imm (17T+ea)

AND Logical AND

O D I T S Z A P C
* * * ? * 0

Όλα τα bit της παραμέτρου προορισμού γίνονται λογικό ΚΑΙ με τα αντίστοιχα bit της
παραμέτρου πηγής και το αποτέλεσμα αποθηκεύεται στην παράμετρο προορισμού

Σύνταξη:
AND reg, reg (3T) AND reg, mem (9T+ea) AND
reg, imm (4T) AND mem, reg (16T+ea) AND
mem, imm (17T+ea)

Παραδείγματα: AND

AX, CX
AND data1, BL AND
AH, date[DI]

CALL Call a procedure

O D I T S Z A P C

Σύνταξη:
CALL nearlabel (19T) CALL mem (21T+ea)
CALL farlabel (28T) CALL reg (16T)

Με την εντολή CALL μεταφερόμαστε στην διεύθυνση που υποδεικνύει η παράμετρος


προορισμού. Αν αυτή είναι διεύθυνση near (στο ίδιο segment), σώζεται ο ΙΡ στον σωρό,
ενώ αν η διεύθυνση της υπορουτίνας είναι far (σε άλλο segment), σώζονται τόσο ο ΙΡ όσο
και ο CS.
66

Παραδείγματα:

CALL clear_screen
CALL AX CALL
ES:[DI]

CBW Convert byte to word (2T)

O D I T S Z A P C

Σύνταξη:
CBW

Αν το bit προσήμου (MSB) του AL είναι 1 ο AH γίνεται ίσος με FFH αλλιώς γίνεται ίσος
με 00Η (επέκταση προσήμου).

CLC Clear carry flag (2T)

O D I T S Z A P C
0

Θέτει το carry flag ίσο με 0.

CLD Clear direction flag (2T)

O D I T S Z A P C
0

Θέτει το flag κατεύθυνσης ίσο με 0.

CLI Clear interrupt flag (2T)

O D I T S Z A P C
0
67

Θέτει 0 το flag διακοπών.

CMC Complement carry flag (2T)

O D I T S Z A P C
*

Αλλάζει τιμή στο carry flag (το συμπληρώνει).

CMP Compare

O D I T S Z A P C
* * * * * *

Σύνταξη:
CMP reg, reg (3T) CMP reg, mem (9T+ea) CMP
reg, imm (4T) CMP mem, reg (9T+ea) CMP mem,
imm (10T+ea)

Γίνεται η αφαίρεση παράμετρος προορισμού μείον παράμετρος πηγής, χωρίς να αλλάζει


καμία από τις δύο. Η εντολή αυτή επηρεάζει μόνο τα flags ανάλογα με το αποτέλεσμα
της αφαίρεσης.

CMPS, CMPSB, CMPSW Compare strings (32T) O D

I T S Z A P C
* * * * * *

Σύνταξη:
CMPSB
CMPSW

Πραγματοποιεί την σύγκριση (αφαίρεση) του περιεχομένου της διεύθυνσης ES:[DI] από το
περιεχόμενο της DS:[SI], χωρίς να επηρεάζει τις θέσεις αυτές παρά μόνο τα flags. Τα
περιεχόμενα αυτά μπορεί να είναι είτε byte (CMPSB) ,είτε words (CMPSW)
αντίστοιχα. Στην συνέχεια οι SI, DI αυξάνονται κατά 1 (CMPSB) ή 2
68

(CMPSW), αν το D flag = 0, ενώ μειώνονται αντίστοιχα, αν το D flag = 1. Οι εντολές αυτές


χρησιμοποιούνται συχνά μαζί με το REPE ή το REPNE.

CWD Convert word to doubleword (5T) O

D I T S Z A P C

Επεκτείνει το bit προσήμου του ΑΧ στον DX. Αυτό γίνεται συνήθως πριν την
προσημασμένη διαίρεση (IDIV).

DAA Decimal adjust after addition (4T) O

D I T S Z A P C
? * * * * *

Μετά την πρόσθεση δύο BCD αριθμών μετατρέπει το περιεχόμενο του AL (το
άθροισμα) σε δύο BCD ψηφία.

DAS Decimal adjust after subtraction (4T) O

D I T S Z A P C
? * * * * *

Μετά την αφαίρεση δύο BCD αριθμών διορθώνει το αποτέλεσμα (στον AL), έτσι ώστε
να είναι BCD αριθμός.

DEC Decrement

O D I T S Z A P C
* * * * *
69

Σύνταξη :

DEC reg (3T)


DEC mem (15T+ea)

Αφαιρεί 1 από την παράμετρο προορισμού είτε αυτή είναι byte ή word. Προσοχή:
Δεν επηρεάζει το carry flag.

DIV Divide unsigned

O D I T S Z A P C
? ? ? ? ? ?

Σύνταξη :
DIV reg (162T)
DIV mem (168T)

Αν η παράμετρος προορισμού είναι 8μπιτη διαιρεί τον ΑΧ. Το πηλίκο τοποθετείται στον AL
και το υπόλοιπο στον ΑΗ. Αν η παράμετρος είναι 16μπιτη, διαιρεί τον
32μπιτο αριθμό DX:AX, το πηλίκο τοποθετείται στον ΑΧ και το υπόλοιπο στον DX. Αν το
αποτέλεσμα είναι τόσο μεγάλο ώστε να μην χωρά στον αντίστοιχο καταχωρητή,
προκαλείται μια διακοπή τύπου 0 (int 0).

ESC Escape

O D I T S Z A P C

Σύνταξη:
ESC imm, reg
ESC imm, mem
70

Παρέχει μια εντολή και μια προαιρετική παράμετρο στον συνεπεξεργαστή. Η πρώτη
παράμετρος παρέχει τα bits της αντίστοιχης εντολής του συνεπεξεργαστή, ενώ η δεύτερη
είναι ένας καταχωρητής ή μια θέση μνήμης που μπορεί να χρησιμοποιηθεί από τον
συνεπεξεργαστή.

HLT Halt (2T)

O D I T S Z A P C

Σταματά την λειτουργία της CPU μέχρι να γίνει ένα hardware interrupt. Σημειώστε ότι για
να μπορέσει να συμβεί το τελευταίο, θα πρέπει το Ι flag να είναι 1 (χρήση STI).

IDIV Signed Integer Division

O D I T S Z A P C
? ? ? ? ? ?

Σύνταξη:
IDIV reg (184T)
IDIV mem (190T)

Πραγματοποιεί μια προσημασμένη διαίρεση του DX:AX ή του ΑΧ αντίστοιχα με την


παράμετρο, με τους ίδιους κανόνες που ισχύουν στην εντολή DIV.

IMUL Signed Integer Multiply

O D I T S Z A P C
* ? ? ? ? *

Σύνταξη:
IMUL reg (154T)
IMUL mem (160T)
71

Πολλαπλασιασμός προσημασμένων ακεραίων. Αν η παράμετρος είναι 8μπιτη,


πολλαπλασιάζει τον AL και το γινόμενο καταχωρείται στον ΑΧ. Αν η παράμετρος είναι
16μπιτη, πολλαπλασιάζει τον ΑΧ και το γινόμενο καταχωρείται στο DX:AX (32bit). Τα flags
carry και overflow γίνονται 1 αν το 16μπιτο γινόμενο επεκτείνεται μέχρι τον ΑΗ, ή το
32μπιτο επεκτείνεται μέχρι τον DX.

IN Input from port

O D I T S Z A P C

Σύνταξη :

IN acc, imm (10T) IN acc, DX


(8T)

Ένα byte εισάγεται στον AL ή μια λέξη στον ΑΧ από την αντίστοιχη θύρα (port), της οποίας
η διεύθυνση δίνεται είτε σαν 8μπιτη σταθερά είτε σαν το 16μπιτο περιεχόμενο του DX.

INC Increment

O D I T S Z A P C
* * * * *

Σύνταξη :

INC reg (3T)


INC mem (15T+ea)

Προσθέτει 1 σε έναν καταχωρητή ή θέση μνήμης. Προσοχή : δεν επιδρά στο carry flag.

INT Interrupt (51T)

O D I T S Z A P C
0 0

Σύνταξη :
72

ΙΝΤ imm

Προκαλεί μια διακοπή software (κλήση κάποιας ρουτίνας του DOS ή του BIOS). Πριν
μεταβεί στην διεύθυνση εξυπηρέτησης της αντίστοιχης διακοπής, σώζει στον σωρό τους
καταχωρητές F (flags), CS και ΙΡ.

INTO Interrupt on overflow (53T)

O D I T S Z A P C
* *

Σύνταξη :
ΙΝΤΟ

Αν το overflow flag γίνει 1, προκαλείται μια διακοπή ΙΝΤ 4. Το DOS δεν κάνει τίποτε
όταν γίνει ΙΝΤ 4, αλλά μπορεί ο χρήστης να γράψει την δική του ρουτίνα εξυπηρέτησης της
ΙΝΤ 4.

IRET Return from interrupt (32T)

O D I T S Z A P C
* * * * * * * * *

Σύνταξη : IRET

Επιστρέφει από την ρουτίνα εξυπηρέτησης μιας διακοπής. Επαναφέρει από τον σωρό τους
καταχωρητές F (flags), CS και ΙΡ.

Jcondition Conditional jump (16T/4T) O

D I T S Z A P C

Σύνταξη :
Jcondition shortlabel

Διακλάδωση υπό συνθήκη (condition). Η εντολή αυτή, αν ισχύει η υπό εξέταση συνθήκη,
κάνει ένα σχετικό άλμα (-128 έως +127 θέσεις από την θέση της επόμενης προς εκτέλεση
73

εντολής). Οι εξεταζόμενες συνθήκες μπορεί να είναι οι εξής :

JA/JNA jump if above/not above (παραπάνω/όχι παραπάνω)


JAE/JNAE jump if/if not above or equal (παραπάνω ή ίσο/όχι παραπάνω ή ίσο)
JB/JNB jump if below/not below (παρακάτω/όχι παρακάτω)
JBE/JNBE jump if/if not below or equal (παρακάτω ή ίσο/όχι παρακάτω ή ίσο)
JG/JNG jump if greater/not greater (μεγαλύτερο/όχι μεγαλύτερο)
JGE/JNGE jump if/if not greater or equal (μεγαλύτερο ή ίσο/όχι μεγαλύτερο ή ίσο)
JL/JNL jump if less/not less (μικρότερο/όχι μικρότερο)
JLE/JNLE jump if/if not less or equal (μικρότερο ή ίσο/όχι μικρότερο ή ίσο)
JE/JNE jump if equal/not equal (ίσο /όχι ίσο)
JZ/JNZ jump if zero/not zero (Ζ=1 / Ζ=0) JS/JNS
jump if sign / not sign (S=1 / S=0) JC/JNC
jump if carry / not carry (C=1 / C=0)
JO/JNO jump if overflow /not overflow (O=1 / O=0)
JP/JNP jump if parity /not parity (P=1 / P=0)
JPE jump if parity even (Ρ=1, άρτια ισοτιμία) JPO
jump if parity odd (P=0, περιττή ισοτιμία)

JCXZ Jump if CX=0 (18T/6T)

O D I T S Z A P C

Σύνταξη :
JCXZ shortlabel

Όταν ο CX είναι ίσος με μηδέν, γίνεται ένα σχετικό άλμα (-128 έως +127 θέσεις από την
επόμενη εντολή) στην θέση που δίνουμε ως παράμετρο.

JMP Jump

O D I T S Z A P C

Σύνταξη :
JMP shortlabel (15T) JMP reg16 (11T) JMP
nearlabel (15T) JMP mem (18T+ea) JMP
farlabel (15T)
74

Διακλάδωση χωρίς συνθήκη. Με την εντολή αυτή μπορούμε να μεταφερθούμε σε


οποιοδήποτε σημείο της μνήμης, δίνοντας τον προορισμό μας είτε άμεσα ( με ένα short,
near ή far label), είτε έμμεσα (με το περιεχόμενο ενός 16μπιτου καταχωρητή ή του
περιεχομένου θέσης μνήμης – 16 ή 32 bit).

LAHF Load flags into AH (4T)

O D I T S Z A P C

Σύνταξη : LAHF

Φορτώνει το λιγότερο σημαντικό byte του F register (δηλ. τα flags C, P, A, Z και S)


στον καταχωρητή ΑΗ.

LDS Load register and DS (16T+ea) O D

I T S Z A P C

Σύνταξη :
LDS reg16, mem32

Φορτώνει τα περιεχόμενα μιας διπλής λέξης μνήμης (mem32) στους καταχωρητές DS


και reg16, όπου ο τελευταίος δίδεται σαν παράμετρος.

Παράδειγμα :
LDS BX, fname
Μετά την εκτέλεση της εντολής, ο BX θα έχει ως νέο περιεχόμενο το περιεχόμενο των
θέσεων μνήμης fname, fname +1, και ο DS θα έχει τα περιεχόμενα των θέσεων fname+2,
fname+3.

LEA Load Effective Address (2T+ea) O D

I T S Z A P C
75

Σύνταξη :

LEA reg, mem

Υπολογίζει και φορτώνει στον αντίστοιχο καταχωρητή το offset της διεύθυνσης του
τελεστή μνήμης mem.

LES Load register and ES (16T+ea)

O D I T S Z A P C

Σύνταξη :
LES reg16, mem32

Φορτώνει τα περιεχόμενα μιας διπλής λέξης μνήμης (mem32) στους καταχωρητές ES


και reg16, όπου ο τελευταίος δίδεται σαν παράμετρος.

Παράδειγμα :
LES BX, fname
Μετά την εκτέλεση της εντολής, ο BX θα έχει ως νέο περιεχόμενο το περιεχόμενο των
θέσεων μνήμης fname, fname +1, και ο ES θα έχει τα περιεχόμενα των θέσεων fname+2,
fname+3.

LOCK Lock the bus (2T)

O D I T S Z A P C

Σύνταξη :
LOCK instruction

Κατά την διάρκεια εκτέλεσης της εντολής που δίνεται σαν παράμετρος, απαγορεύεται να
λειτουργήσουν άλλοι επεξεργαστές, ώστε να μην αλλάξει κάποιο κομμάτι της μνήμης.
Παράδειγμα :
LOCK ADD AH, 14
76

LODS, LODSB, LODSW Load string (12T)

O D I T S Z A P C

Σύνταξη :
LODS mem
LODSB LODSW

Η LODSB φορτώνει το byte DS:[SI] στον ΑL και ο SI αυξάνει κατά 1 (αν το D


flag=0) ή μειώνεται κατά 1 αν D=1. Ομοίως, η LODSW φορτώνει 2 byte από την
διεύθυνση DS:SI στον ΑΧ, και ο SI αυξάνεται ή μειώνεται αντίστοιχα κατά 2. Σπανιότερα
χρησιμοποιείται η LODS μαζί με τον τελεστή μνήμης mem που είναι ένα label. Αν το label
αυτό έχει οριστεί σαν byte (με το DB) η εντολή λειτουργεί σαν την LODSB, ενώ αν έχει
οριστεί σαν word (με την DW), η εντολή λειτουργεί σαν την LODSW.

LOOP Loop (17T/5T)

O D I T S Z A P C

Σύνταξη :
LOOP shortlabel

Μειώνει τον CX κατά 1, και εφόσον αυτός δεν έχει γίνει 0, πηγαίνει στο short label
(+127 έως –128 θέσεις από την επόμενη εντολή) που δίνεται σαν παράμετρος.

LOOPE, LOOPZ Loop if equal (zero) (18T/6T) O

D I T S Z A P C

Σύνταξη :
LOOPE shortlabel
LOOPZ shortlabel
77

Οι δύο εντολές είναι ακριβώς ίδιες. Μειώνουν τον CX κατά 1 και εφόσον είναι διάφορος του
0 και επιπλέον Ζ=1 κάνουν σχετικό άλμα (-128 έως +127 θέσεις από την επόμενη εντολή).

LOOPNE, LOOPNZ Loop if not equal (not zero) (19T/5T) O D

I T S Z A P C

Σύνταξη :
LOOPNE shortlabel
LOOPNZ shortlabel

Οι δύο εντολές είναι ακριβώς ίδιες. Μειώνουν τον CX κατά 1 και εφόσον είναι διάφορος του
0 και επιπλέον Ζ=0 κάνουν σχετικό άλμα (-128 έως +127 θέσεις από την επόμενη εντολή).

MOV Move

O D I T S Z A P C

Σύνταξη :
MOV reg, reg (2T) MOV reg, imm (4T)
MOV mem, reg (9T+ea) MOV mem, imm (10T+ea)
MOV reg, mem (10T+ea) MOV mem, seg (9T+ea) MOV
reg, seg (2T) MOV seg, mem (8T+ea) MOV
seg, reg (2T)

Η εντολή MOV αντιγράφει το περιεχόμενο της παραμέτρου πηγής στην παράμετρο


προορισμού, αρκεί βέβαια και οι δυο να είναι του ιδίου μεγέθους.

MOVS, MOVSB, MOVSW Move string (18T) O

D I T S Z A P C

Σύνταξη :
78

MOVSB MOVS dest, source


MOVSW

H MOVSB αντιγράφει ένα byte από την διεύθυνση DS:SI στην ES:DI, και στην συνέχεια
αυξάνει τους SI, DI κατά 1 (αν το flag D=0), αλλιώς τους μειώνει κατά 1 (αν D=1).
Ομοίως, η εντολή MOVSW αντιγράφει ένα word από την DS:SI στην ES:DI και στην
συνέχεια αυξάνει ή μειώνει αντίστοιχα τους SI, DI κατά 2.

Σπανιότερα χρησιμοποιείται η MOVS με υποχρεωτικές παραμέτρους δύο τελεστές μνήμης.


Αν αυτοί οι τελεστές είναι bytes, τότε η εντολή λειτουργεί σαν την MOVSB, ενώ αν οι
τελεστές είναι words, τότε η MOVS λειτουργεί σαν την MOVSW.

MUL Unsigned integer multiply

O D I T S Z A P C
* ? ? ? ? *

Σύνταξη :
MUL reg (118T) MUL
mem (139T)

Πολλαπλασιασμός μη προσημασμένων ακεραίων.


Αν η παράμετρος είναι 8μπιτη, πολλαπλασιάζει το περιεχόμενο του AL και το αποτέλεσμα
καταχωρείται στον ΑΧ. Αν η παράμετρος είναι 16μπιτη, πολλαπλασιάζει το περιεχόμενο του
ΑΧ και το αποτέλεσμα καταχωρείται στους DX:AX.

NEG Negate

O D I T S Z A P C
* * * * * *

Σύνταξη :
ΝEG reg (3T)
NEG mem (16T+ea)

Μετατρέπει το περιεχόμενο της παραμέτρου προορισμού στο συμπλήρωμα ως προς 2 (2s


complement).
79

NOP No operation (3T)

O D I T S Z A P C

Η εντολή αυτή δεν κάνει τίποτα, αλλά μπορεί να χρησιμοποιηθεί σε βρόγχους


χρονισμού ή ρουτίνες καθυστέρησης.

ΝΟΤ Not

O D I T S Z A P C

Σύνταξη :
NOT reg (3T)
NOT mem (16T+ea)

Εκτελεί λογικό ΝΟΤ στην παράμετρο που του δίνουμε, δηλαδή αντιστρέφει όλα τα
bits.

OR Logical OR

O D I T S Z A P C
0 * * ? * 0

Σύνταξη :
OR reg, reg (3T) OR reg, imm (4T)
OR mem, reg (16T+ea) OR mem, imm (17T+ea)
OR reg, mem (9T+ea)

Εκτελεί την πράξη λογικό OR ανάμεσα στις παραμέτρους πηγής και προορισμού (τα ίδιας
τάξης bits γίνονται OR), και το αποτέλεσμα καταχωρείται στην παράμετρο προορισμού.

OUT Output to port

O D I T S Z A P C
80

Σύνταξη :
OUT imm8, acc (10T) OUT
DX, acc (8T)

Στέλνει ένα byte (AL) ή ένα word (AX) στην θύρα (port) που καθορίζεται είτε άμεσα σαν
ένας αριθμός από 00Η έως FFH, είτε έμμεσα σαν ένας 16μπιτος (0-FFFFH) αριθμός από το
περιεχόμενο του DX.

POP Pop from stack

O D I T S Z A P C

Σύνταξη :
POP reg16 (8T) POP seg (8T) POP
mem16 (17T+ea)

Αντιγράφει την λέξη που βρίσκεται στην κορυφή του σωρού στην 16μπιτη
παράμετρο προορισμού και στην συνέχεια αυξάνει τον SP κατά 2.

POPF Pop flags (8T)

O D I T S Z A P C
* * * * * * * * *

Αντιγράφει στον flag register τα δύο bytes που βρίσκονται στην κορυφή του σωρού και
κατόπιν αυξάνει τον SP κατά 2.

PUSH Push on stack

O D I T S Z A P C

Σύνταξη :
PUSH reg16 (11T) PUSH seg (10T)
PUSH mem16 (16T+ea)
112

Αφαιρεί 2 από τον SP και αντιγράφει το περιεχόμενο της παραμέτρου προορισμού στο
σημείο που δείχνει ο SP (κορυφή του σωρού).

PUSHF Push flags (10Τ)

O D I T S Z A P C

Αφαιρεί 2 από τον SP και αντιγράφει το περιεχόμενο του flag register στο σημείο που
δείχνει ο SP (κορυφή του σωρού).

RCL Rotate carry left

O D I T S Z A P C
* *

Σύνταξη :
RCL reg, 1 (2Τ) RCL mem, 1 (15Τ+ea)
RCL reg, CL (8T+4*CL) RCL mem, CL (20T+4*CL)

Περιστρέφει αριστερά την παράμετρο προορισμού. Το carry flag γράφεται στο χαμηλότερο
bit, ενώ το υψηλότερο bit αντιγράφεται στο carry flag. Η σταθερά 1 ή ο καταχωρητής CL
μπορεί να χρησιμοποιηθούν σαν μετρητές που θα καθορίσουν τον αριθμό των περιστροφών.

RCR Rotate carry right

O D I T S Z A P C
* *

Σύνταξη :
RCR reg, 1 (2Τ) RCR mem, 1 (15Τ+ea)
RCR reg, CL (8T+4*CL) RCR mem, CL (20T+4*CL)

Περιστρέφει δεξιά την παράμετρο προορισμού. Το carry flag γράφεται στο


υψηλότερο bit, ενώ το χαμηλότερο bit αντιγράφεται στο carry flag. Η σταθερά 1 ή ο
καταχωρητής CL μπορεί να χρησιμοποιηθούν σαν μετρητές που θα καθορίσουν τον
113

αριθμό των περιστροφών.

REP Repeat string (9Τ+?)

O D I T S Z A P C

Επαναλαμβάνει την εντολή χειρισμού string που ακολουθεί τόσες φορές όσο το
περιεχόμενο του CX. Κάθε φορά μειώνει τον CX κατά 1, μέχρι αυτός να γίνει 0.

Παράδειγμα (με την εντολή MOVS) :


REP MOVS dest, source (9+17*CX)T

REPZ, REPE, REPNZ, REPNE Conditional repeat string (9T+?) O

D I T S Z A P C
*

Λειτουργεί σαν την εντολή REP μόνο εφόσον ισχύει η αντίστοιχη συνθήκη. Οι
REPZ, REPE λειτουργούν όταν zero flag =1, ενώ οι REPNZ, REPNE, όταν Ζ=0.
Το zero flag (Z) επηρεάζεται μόνο από τις εντολές SCAS, CMPS.

Παραδείγματα (με την SCAS) :


REPZ SCAS dest REPNZ SCASB REPE
SCASW REPNE SCAS dest

RET, RETN, RETF Return from procedure

O D I T S Z A P C

Σύνταξη :
RET RET imm8
RETN (16T) RETN imm8 (20T) RETF
(26T) RETF imm8 (25T)
114

Επιστροφή από υπορουτίνα. Η RETΝ επιστρέφει από ρουτίνα NEAR, δηλαδή τοποθετεί την
κορυφή του σωρού στον ΙΡ. Η RETF επιστρέφει από ρουτίνα FAR, δηλαδή τοποθετεί την
κορυφή του σωρού στον ΙΡ και στο CS. Η εντολή RET μπορεί να είναι είτε near είτε far,
εξαρτάται το πώς έχει δηλωθεί η αντίστοιχη ρουτίνα. Προαιρετικά, μπορούμε στις εντολές
αυτές να προσθέσουμε έναν 8μπιτο αριθμό, ο οποίος προστίθεται στον SP. Η χρήση της
τελευταίας δυνατότητας είναι σπάνια στην assembly, αλλά έχει σημασία όταν η ρουτίνα μας
χρησιμοποιείται από γλώσσες ανωτέρου επιπέδου (C ή PASCAL). Επίσης η χρήση των
RETN, RETF πρέπει να αποφεύγεται και να χρησιμοποιείται μόνο η RET σε συνδυασμό
με καθορισμό της αντίστοιχης ρουτίνας σαν near ή far.

ROL Rotate left

O D I T S Z A P C
* *

Σύνταξη :
ROL reg, 1 (2T) ROL mem, 1 (15T+ea) ROL reg,
CL (8+4*CL)T ROL mem, CL (20+4*CL)T

Περιστρέφει την παράμετρο προορισμού αριστερά. Το υψηλότερης τάξης bit αντιγράφεται


τόσο στο carry flag, όσο και στο χαμηλότερης τάξης bit. Η σταθερά 1 ή ο καταχωρητής CL
μπορεί να χρησιμοποιηθούν σαν μετρητές που να καθορίζουν τον αριθμό των επαναλήψεων
της εντολής αυτής.

ROR Rotate right

O D I T S Z A P C
* *

Σύνταξη :
ROR reg, 1 (2Τ) ROR mem, 1 (15T+ea)
ROR reg, CL (8+4*CL)T ROR mem, CL (20+4*CL)T

Περιστρέφει την παράμετρο προορισμού δεξιά. Το χαμηλότερης τάξης bit αντιγράφεται τόσο
στο carry flag, όσο και στο υψηλότερης τάξης bit. H σταθερά 1 ή ο καταχωρητής CL μπορεί
να χρησιμοποιηθούν σαν μετρητές που να καθορίζουν τον αριθμό των επαναλήψεων της
εντολής αυτής.
115

SAHF Store AH into flags (4T)

O D I T S Z A P C
* * * * *

Αντιγράφει τον ΑΗ στο χαμηλής τάξης byte του Flag register.

SAL Shift arithmetic left

O D I T S Z A P C
* * * ? * *

Σύνταξη :
SAL reg, 1 (2T) SAL mem, 1 (15T+ea)
SAL reg, CL (8+4*CL)T SAL mem, CL (20+4*C L)T

Μετατόπιση όλων των bit της παραμέτρου προορισμού κατά μία θέση αριστερά. Το
υψηλότερης τάξης bit αντιγράφεται στο carry flag και το χαμηλότερης τάξης bit γίνεται 0. H
σταθερά 1 ή το περιεχόμενο του καταχωρητή CL καθορίζουν τον αριθμό των επαναλήψεων
της εντολής. Η εντολή αυτή είναι ίδια με την SHL.

SAR Shift arithmetic right

O D I T S Z A P C
* * * ? * *

Σύνταξη :
SAR reg, 1 (2T) SAR mem, 1 (15T+ea)
SAR reg, CL (8+4*CL)T SAR mem, CL (20+4*CL)T

Μετατόπιση όλων των bit της παραμέτρου προορισμού κατά μία θέση δεξιά. Το χαμηλότερης
τάξης bit αντιγράφεται στο carry flag και το υψηλότερης τάξης bit παραμένει στην
προηγούμενη τιμή του. H σταθερά 1 ή το περιεχόμενο του καταχωρητή CL καθορίζουν τον
αριθμό των επαναλήψεων της εντολής.
116

SBB Subtract with borrow

O D I T S Z A P C
* * * * * *

Σύνταξη :
SBB reg, reg (3T) SBB reg, imm (4T)
SBB mem, reg (16T+ea) SBB mem, imm (17T+ea)
SBB reg, mem (9T+ea)

Αφαίρεση με δανεικό. Από την παράμετρο προορισμού αφαιρείται η παράμετρος


πηγής και το carry flag. Το αποτέλεσμα καταχωρείται στην παράμετρο προορισμού.

SCAS, SCASB, SCASW Scan string (15T) O

D I T S Z A P C
* * * * * *

Σύνταξη :
SCASB SCASW
SCAS dest

Η εντολή SCASB συγκρίνει το περιεχόμενο του AL με την θέση μνήμης ES:DI και στην
συνέχεια αυξάνει τον DI κατά 1 (αν D flag = 0) ή τον μειώνει κατά 1 (αν D=1). Ομοίως, η
SCASW συγκρίνει τον ΑΧ με περιεχόμενο της θέσης μνήμης ES:DI (2 bytes), και αυξάνει ή
μειώνει αντίστοιχα τον DI κατά 2. Η SCAS χρειάζεται και μια παράμετρο. Αν αυτή είναι
8μπιτη, τότε η SCAS λειτουργεί σαν την SCASB, ενώ αν η παράμετρος είναι 16μπιτη,
λειτουργεί σαν την SCASW.

SHL Shift left

O D I T S Z A P C
* * * ? * *

Σύνταξη :
SHL reg, 1 (2T) SHL mem, 1 (15T+ea)
SHL reg, CL (8+4*CL)T SHL mem, CL (20+4*CL)T
117

Μετατόπιση όλων των bit της παραμέτρου προορισμού κατά μία θέση αριστερά. Το
υψηλότερης τάξης bit αντιγράφεται στο carry flag και το χαμηλότερης τάξης bit γίνεται 0. H
σταθερά 1 ή το περιεχόμενο του καταχωρητή CL καθορίζουν τον αριθμό των επαναλήψεων
της εντολής. Η εντολή αυτή είναι ίδια με την SAL.

SHR Shift right

O D I T S Z A P C
* * * ? * *

Σύνταξη :
SΗR reg, 1 (2T) SΗR mem, 1 (15T+ea)
SΗR reg, CL (8+4*CL)T SΗR mem, CL (20+4*CL)T

Μετατόπιση όλων των bit της παραμέτρου προορισμού κατά μία θέση δεξιά. Το χαμηλότερης
τάξης bit αντιγράφεται στο carry flag και το υψηλότερης τάξης bit γεμίζει με το 0 . H σταθερά
1 ή το περιεχόμενο του καταχωρητή CL καθορίζουν τον αριθμό των επαναλήψεων της
εντολής.

STC Set Carry Flag (2T)

O D I T S Z A P C
1

Θέτει το carry flag ίσο με 1.

STD Set Direction Flag (2T)

O D I T S Z A P C
1

Θέτει 1 το Direction flag.


118

STI Set Interrupt Flag (2T)

O D I T S Z A P C
1

Θέτει 1 το Interrupt flag.

STOS, STOSB, STOSW Store string (11T) O D

I T S Z A P C

Σύνταξη :
STOSB STOS mem
STOSW

Η εντολή STOSB αντιγράφει το περιεχόμενο του AL στην θέση μνήμης ES:DI, και αν
D=0 ο DI αυξάνεται κατά 1, ενώ αν D=1, ο DI μειώνεται κατά 1. Ομοίως, η STOSW
αντιγράφει τον ΑΧ στην θέση ES:DI (2 bytes) και αυξάνει ή μειώνει αντίστοιχα τον DI κατά
2. Η STOS χρειάζεται και μια παράμετρο, το μέγεθος της οποίας (byte ή word), καθορίζει αν
η STOS θα λειτουργήσει σαν την STOSB ή σαν την STOSW.

SUB Subtract

O D I T S Z A P C
* * * * * *

Σύνταξη :
SUB reg, reg (3T) SUB reg, imm (4T)
SUB mem, reg (16T+ea) SUB mem, imm (17T+ea)
SUB reg, mem (9T+ea)

Η παράμετρος πηγής αφαιρείται από την παράμετρο προορισμού και το αποτέλεσμα


καταχωρείται στην παράμετρο προορισμού.

TEST Test

O D I T S Z A P C
0 * * ? * 0
119

Σύνταξη :
TEST reg, reg (5T) TEST reg, imm (4T)
TEST mem, reg (9T+ea) TEST mem, imm (11T+ea)
TEST reg, mem (9T+ea)

Εκτελεί ένα λογικό AND ανάμεσα σε όλα τα ίδια τάξης bit της παραμέτρου προορισμού και
της παραμέτρου πηγής, χωρίς να επηρεάζει τίποτε άλλο παρά μόνο τα flags.

WAIT Wait for coprocessor (4T)

O D I T S Z A P C

Σταματά την λειτουργία της CPU μέχρι ο συνεπεξεργαστής εκτελέσει την τρέχουσα
εντολή του.

XCHG Exchange

O D I T S Z A P C

Σύνταξη :
XCHG reg, reg (4T) XCHG mem, reg (17T+ea)
XCHG reg, mem (17T+ea)

Ανταλλάζει αμοιβαία τα περιεχόμενα πηγής και προορισμού.

XLAT Translate byte (11T)

O D I T S Z A P C

Σύνταξη : XLAT XLAT


mem
120

Αντιγράφει στον AL το περιεχόμενο της DS:[BX+AL], δηλαδή μετατοπίζεται μέσα στον


πίνακα που αρχίζει από την διεύθυνση DS:BX τόσες θέσεις όσο το περιεχόμενο του AL και
αντιγράφει το byte που βρίσκεται στην θέση αυτή στον AL.

XOR Exclusive OR

O D I T S Z A P C
0 * * ? * 0

Σύνταξη :
XOR reg, reg (3T) XOR reg, imm (4T)
XOR mem, reg (16T+ea) XOR mem, imm (17T+ea)
XOR reg, mem (9T+ea)

Κάθε bit της παραμέτρου πηγής γίνεται XOR με το αντίστοιχης τάξης bit της
παραμέτρου προορισμού. Το αποτέλεσμα καταχωρείται στην παράμετρο προορισμού.
120

ΠΑΡΑΡΤΗΜΑ Δ

Οι διακοπές του DOS και του BIOS

Στο Παράρτημα αυτό δίδονται πληροφορίες για τις σημαντικότερες από


τις διακοπές που χρησιμοποιούνται στον 8086 καθώς και στους νεώτερους
επεξεργαστές. Πρώτα παραθέτεται ένας πίνακας με όλα τα interrupts,
τον χρήστη (CPU, BIOS κτλ) καθώς και την λειτουργία καθενός από αυτά.
Στην συνέχεια εξηγείται αναλυτικά η χρήση όλων των συναρτήσεων για τα
σημαντικότερα από τα interrupts αυτά.

ΣΥΝΟΠΤΙΚΟΣ ΠΙΝΑΚΑΣ ΟΛΩΝ ΤΩΝ INTERRUPTS

INT Χρήστης Λειτουργία

0 CPU divide by zero


1 CPU single step
2 CPU non-maskable
3 CPU breakpoint
4 CPU overflow trap
5 BIOS print screen
6 CPU Invalid opcode (186,286,386)
7 CPU coprocessor not available (286,386)
8 IRQ0 ~timer~ (55ms intervals, 18.21590 per second)
9 IRQ1 keyboard service required
A IRQ2 slave ~8259~ or EGA/VGA vertical retrace
B IRQ3 COM2 service required (PS/2 MCA COM3-COM8)
C IRQ4 COM1 service required
D IRQ5 fixed disk or data request from LPT2
E IRQ6 floppy disk service required
F IRQ7 data request from LPT1 (unreliable on IBM mono)
10 BIOS video (see ~INT 10~)
11 BIOS Equipment determination
12 BIOS memory size
13 BIOS disk I/O service
14 BIOS serial communications (see ~INT 14~)
15 BIOS system services, cassette
121

16 BIOS keyboard services (see ~INT 16~)


17 BIOS parallel printer
18 BIOS ROM BASIC loader
19 BIOS bootstrap loader
1A BIOS time of day
1B BIOS user defined ctrl-break handler
1C BIOS user defined clock tick handler
1D BIOS ~6845~ video parameter pointer
1E BIOS diskette parameter pointer (base table)
1F BIOS graphics character table
20 DOS general program termination
21 DOS function request services (see ~INT 21~)
22 DOS terminate address
23 DOS control break termination address
24 DOS critical error handler
25 DOS absolute disk read
26 DOS absolute disk write
27 DOS terminate and stay resident
28 DOS idle loop, issued by DOS when idle
29 DOS fast TTY console I/O
2A DOS critical section and NETBIOS
2B DOS internal, simple IRET in DOS 2.0-5.0
2C DOS internal, simple IRET in DOS 2.0-5.0
2D DOS internal, simple IRET in DOS 2.0-5.0
2E DOS exec command from base level command
interpreter
2F DOS multiplexer
30-31 CPM far jump vector for CPM (not an interrupt)
31 DPMI DOS Protected Mode Interface (for DOS extenders)
32 reserved
33 mouse support (see INT 33)
34-3E Microsoft/Borland floating point emulation
3F overlay manager
40 BIOS hard disk
41 BIOS fixed disk 0 parameters pointer
42 BIOS relocated video handler (EGA/VGA/PS)
43 BIOS user font table (EGA/VGA/PS)
44 BIOS first 128 graphics characters (also Netware)
45 BIOS reserved for BIOS
46 BIOS fixed disk 1 parameters ptr
47 BIOS reserved for BIOS
122

48 BIOS PCjr cordless keyboard translation


49 BIOS PCjr non-keyboard scancode translation table
4A BIOS user alarm (AT,CONV,PS/2)
4B-4F BIOS reserved
50 BIOS periodic alarm from timer (PS/2)
51-58 BIOS reserved
59 BIOS GSS Computer Graphics Interface
5A BIOS cluster adapter BIOS entry point
5B BIOS cluster adapter boot
5C NETBIOS NETBIOS interface, TOPS interface
5D-5F BIOS reserved for BIOS
60-67 reserved for user software interrupts
67 EMS LIM/EMS specification
68 APPC
69-6B reserved by IBM
6C DOS DOS 3.2 real time clock update
BIOS system resume vector
6D-6F reserved
70 IRQ8 real time clock (AT,XT286,PS50+)
71 IRQ9 software redirected to IRQ2 (AT,XT286,PS50+)
72 IRQ10 reserved (AT,XT286,PS50+)
73 IRQ11 reserved (AT,XT286,PS50+)
74 IRQ12 mouse interrupt (PS50+)
75 IRQ13 numeric coprocessor NMI error (AT,XT286,PS50+)
76 IRQ14 fixed disk controller (AT,XT286,PS50+)
77 IRQ15 reserved (AT,XT286,PS50+)
78-79 unused
80-85 ROM BASIC
86-F0 DOS reserved for BASIC interpreter use
86 NETBIOS NETBIOS relocated INT 18
E0 CPM CP/M 86 function calls
F1-FF reserved by IBM

Όλες οι διακοπές σώζουν τα flags και τους CS, IP στον σωρό.

Τα πρώτα 5 interrupts έχουν ειδική σημασία, όπως είδαμε στο


αντίστοιχο κεφάλαιο. Για τα υπόλοιπα έχουμε αναλυτικά:
123

INT 5 - Print Screen

no input data

related memory:

50:00 = 00 Print screen has not been called, or upon return


from a call there were no errors
= 01 Print screen is already in progress
= FF Error encountered during printing

INT 9 - Keyboard Interrupt (Hardware Handler)

no input data

related memory:
40:17 = updates keyboard flag byte 0
40:18 = updates keyboard flag byte 1
40:1A = queue head ptr is set to buffer start if Ctrl-Break is
hit
40:1C = updates buffer tail pointer for each keystroke; sets
queue tail ptr is set to queue start if Ctrl-Break is hit
40:1E = updates keyboard buffer (32 bytes)
40:71 = updates bit 7 of the BIOS break flag if Ctrl-Break is
hit
40:72 = updates reset flag with 1234H if Ctrl-Alt-Del pressed
40:96 = indicates keyboard type (AT,PS/2)
40:97 = updates keyboard LED flags (AT,PS/2)
FFFF:0 = reboot code called if Ctrl-Alt-Del pressed

- records key press and key release via IRQ1/8259 and


stores scan codes in the BIOS buffer located at 40:1C
- keyboard controllers also buffer data when interrupts are
disabled at the 8259 interrupt controller
- keyboard controller is capable of storing 16 keystrokes
even when interrupts are disabled at the 8259
- normal INT 9 execution takes approximately 500 microseconds;
at least one standard XT BIOS is known to take up to 1.3
milliseconds to execute
124

INT 10 - Video BIOS Services

Συνολικά οι συναρτήσεις του ΙΝΤ 10Η είναι οι εξής (ο αριθμός που


χαρακτηρίζει την συνάρτηση είναι το περιεχόμενο του ΑΗ):

INT 10,0~ - Set video mode


INT 10,1~ - Set cursor type
INT 10,2~ - Set cursor position
INT 10,3~ - Read cursor position
INT 10,4~ - Read light pen
INT 10,5~ - Select active display page
INT 10,6~ - Scroll active page up
INT 10,7~ - Scroll active page down
INT 10,8~ - Read character and attribute at cursor
INT 10,9~ - Write character and attribute at cursor
INT 10,A~ - Write character at current cursor
INT 10,B~ - Set color palette
INT 10,C~ - Write graphics pixel at coordinate
INT 10,D~ - Read graphics pixel at coordinate
INT 10,E~ - Write text in teletype mode
INT 10,F~ - Get current video state
INT 10,10~ - Set/get palette registers (EGA/VGA)
INT 10,11~ - Character generator routine (EGA/VGA)
INT 10,12~ - Video subsystem configuration (EGA/VGA)
INT 10,13~ - Write string (BIOS after 1/10/86)
INT 10,14~ - Load LCD char font (convertible)
INT 10,15~ - Return physical display parms (convertible)
INT 10,1A~ - Video Display Combination (VGA)
INT 10,1B~ - Video BIOS Functionality/State Information
(MCGA/VGA)
INT 10,1C~ - Save/Restore Video State (VGA only)
INT 10,FE~ - Get DESQView/TopView Virtual Screen Regen Buffer
INT 10,FF~ - Update DESQView/TopView Virtual Screen Regen
Buffer

Warning: Some BIOS implementations have a bug that causes


register BP to be destroyed. It is advisable to save BP before a
call to Video BIOS routines on these systems.
125

- registers CS, DS, ES, SS, BX, CX, DX are preserved unless
explicitly changed

INT 10,0 - Set Video Mode

AH = 00
AL = 00 40x25 B/W text (CGA,EGA,MCGA,VGA)
= 01 40x25 16 color text (CGA,EGA,MCGA,VGA)
= 02 80x25 16 shades of gray text (CGA,EGA,MCGA,VGA)
= 03 80x25 16 color text (CGA,EGA,MCGA,VGA)
= 04 320x200 4 color graphics (CGA,EGA,MCGA,VGA)
= 05 320x200 4 color graphics (CGA,EGA,MCGA,VGA)
= 06 640x200 B/W graphics (CGA,EGA,MCGA,VGA)
= 07 80x25 Monochrome text (MDA,HERC,EGA,VGA)
= 08 160x200 16 color graphics (PCjr)
= 09 320x200 16 color graphics (PCjr)
= 0A 640x200 4 color graphics (PCjr)
= 0B Reserved (EGA BIOS function 11)
= 0C Reserved (EGA BIOS function 11)
= 0D 320x200 16 color graphics (EGA,VGA)
= 0E 640x200 16 color graphics (EGA,VGA)
= 0F 640x350 Monochrome graphics (EGA,VGA)
= 10 640x350 16 color graphics (EGA or VGA with 128K)
640x350 4 color graphics (64K EGA)
= 11 640x480 B/W graphics (MCGA,VGA)
= 12 640x480 16 color graphics (VGA)
= 13 320x200 256 color graphics (MCGA,VGA)
= 8x EGA, MCGA or VGA ignore bit 7, see below
= 9x EGA, MCGA or VGA ignore bit 7, see below

- if AL bit 7=1, prevents EGA,MCGA & VGA from clearing display


- function updates byte at 40:49; bit 7 of byte 40:87
(EGA/VGA Display Data Area) is set to the value of AL bit 7

INT 10,1 - Set Cursor Type

AH = 01
CH = cursor starting scan line (cursor top) (low order 5 bits)
CL = cursor ending scan line (cursor bottom) (low order 5 bits)
126

returns nothing

- cursor scan lines are zero based


- cursor size can also be set via the ~6845~ CRT controller
- cursor size can be determined using the CRTC, ~INT 10,3~ or
the BIOS Data Area bytes 40:60 (ending scan line) and 40:61 (starting
scan line)
- the following is a list of the cursor scan lines associated
with most common adapters; screen sizes over 40 lines may differ
depending on adapters.

Line Starting Ending Character


Video Count Scan Line Scan Line Point Size

CGA 25 06 07 08
MDA 25 0B 0C 0E
EGA 25 06 07 0E
EGA 43 04/06 07 08
VGA 25 0D 0E 10
VGA 40 08 09 0A
VGA 50 06 07 08

- use CX = 2000h to disable cursor

INT 10,2 - Set Cursor Position

AH = 02
BH = page number (0 for graphics modes)
DH = row
DL = column

returns nothing

- positions relative to 0,0 origin


- 80x25 uses coordinates 0,0 to 24,79; 40x25 uses 0,0 to
24,39
- the 6845 can also be used to perform this function
- setting the data in the BIOS Data Area at location 40:50 does
not take immediate effect and is not recommended
127

INT 10,3 - Read Cursor Position and Size

AH = 03
BH = video page

on return:
CH = cursor starting scan line (low order 5 bits)
CL = cursor ending scan line (low order 5 bits)
DH = row
DL = column

- returns data from ~BIOS DATA AREA~ locations 40:50, 40:60 and
40:61
- the ~6845~ can also be used to read the cursor position
- the return data can be circumvented by direct port I/O to the
6845 CRT Controller since this function returns the data found in the
BIOS Data Area without actually checking the controller

INT 10,4 - Read Light Pen Position

AH = 04

on return:
AH = 0 light pen switch not triggered
= 1 light pen triggered
BX = pixel column (0-319 or 0-639, mode dependent)
CH = raster line (0-199) (CGA and EGA modes 4, 5 and 6)
CX = raster line (EGA modes except 4, 5 and 6)
DH = row (0-24)
DL = column (0-79 or 0-79 mode dependent)

- data returned as a byte coordinate, leaving horizontal


accuracy to within 2 pixels (320) or 4 pixels (640)
- vertical accuracy within 2 lines
- PS/2's don't support the light pen interface
128

INT 10,5 - Select Active Display Page

AH = 05
AL = new page number

INT 10,6 - Scroll Window Up

AH = 06
AL = number of lines to scroll, previous lines are
blanked, if 0 or AL > screen size, window is blanked
BH = attribute to be used on blank line
CH = row of upper left corner of scroll window
CL = column of upper left corner of scroll window
DH = row of lower right corner of scroll window
DL = column of lower right corner of scroll window

returns nothing

- in video mode 4 (300x200 4 color) on the EGA, MCGA and VGA


this function scrolls page 0 regardless of the current page
- can be used to scroll graphics screens, using character
coords
- on CGA's this function disables video adapter, causing
flitter

INT 10,7 - Scroll Window Down

AH = 07
AL = number of lines to scroll, previous lines are
blanked, if 0 or AL > screen size, window is blanked
BH = attribute to be used on blank line
CH = row of upper left corner of scroll window
CL = column of upper left corner of scroll window
DH = row of lower right corner of scroll window
DL = column of lower right corner of scroll window

returns nothing

- in video mode 4 (300x200 4 color) on the EGA, MCGA and VGA


this function scrolls page 0 regardless of the current page
129

- can be used to scroll graphics screens, using character


coords
- on CGA's this function disables video adapter, causing
flitter

INT 10,8 - Read Character and Attribute at Cursor Position

AH = 08
BH = display page

on return:
AH = attribute of character (alpha modes only)
AL = character at cursor position

- in video mode 4 (300x200 4 color) on the EGA, MCGA and VGA


this function works only on page zero

INT 10,9 - Write Character and Attribute at Cursor Position

AH = 09
AL = ASCII character to write
BH = display page (or mode 13h, background pixel value)
BL = character attribute (text) foreground color (graphics)
CX = count of characters to write (CX >= 1)

returns nothing

- does not move the cursor


- in graphics mode (except mode 13h), if BL bit 7=1 then
value of BL is XOR'ed with the background color

INT 10,A - Write Character Only at Current Cursor Position

AH = 0A
AL = ASCII character to write
BH = display page (or mode 13h, background pixel value)
BL = foreground color (graphics mode only)
CX = count of characters to write (CX >= 1)

return nothing
130

- similar to ~INT 10,9~ except color ignored in text modes

INT 10,B - Set Color Palette

AH = 0B
BH = palette color ID
= 0 to set background and border color
= 1 to select 4 color palette
BL = color value (when BH = 0)
= palette value (when BH = 1)

Palette Pixel Color


0 0 current background color
1 green (2)
2 red (4)
3 brown (6)
1 0 current background color
1 cyan (3)
2 magenta (5)
3 white (7)

- does not work for all EGA and VGA video modes
- sets border color in text mode (BH = 0)

INT 10,C - Write Graphics Pixel at Coordinate

AH = 0C
AL = color value (XOR'ED with current pixel if bit 7=1)
BH = page number
CX = column number (zero based)
DX = row number (zero based)

returns nothing

- if bit 7 is 1, color specified is XOR'ed with current pixel


- page number in BH ignored for 320x200 4 color graphics mode
- this function is known to destroy AX and possibly SI and DI
on some PS/2 VGA systems
131

INT 10,D - Read Graphics Pixel at Coordinate

AH = 0D
BH = page number
CX = column number (zero based)
DX = row number (zero based)

on return:
AL = color of pixel read

- 64K IBM EGAs with BIOS dated 9/13/84 in 350 line video
modes, return invalid data in AL
- page number in BH ignored for 320x200 4 color graphics mode

INT 10,E - Write Text in Teletype Mode

AH = 0E
AL = ASCII character to write
BH = page number (text modes)
BL = foreground pixel color (graphics modes)

returns nothing

- cursor advances after write


- characters BEL (7), BS (8), LF (A), and CR (D) are
treated as control codes
- for some older BIOS (10/19/81), the BH register must point
to the currently displayed page
- on CGA adapters this function can disable the video signal
while performing the output which causes flitter.

INT 10,F - Get Video State

AH = 0F

on return:
AH = number of screen columns
AL = mode currently set
BH = current display page
- video modes greater than 13h on EGA, MCGA and VGA indicate
132

~INT 10,0~ was called with the high bit of the mode (AL) set
to 1, meaning the display does not need cleared
- function returns byte value at 40:49; On EGA, MCGA and
VGA bit 7 of register AL is determined by bit 7 of BIOS Data
Area byte 40:87. This bit is usually set by INT 10,0
with bit 7 of the requested mode (in AL) set to 1

INT 10,10 - Set/Get Palette Registers (EGA/VGA)

AH = 10h

AL = 00 set individual palette register


BH = color value
BL = palette register

AL = 01 set border color (overscan register)


BH = color value

AL = 02 set all palette registers and border


ES:DX = pointer to 17 byte table representing 16 palette
registers and border color register

AL = 03 toggle intensity/blinking (EGA)


BL = 0 enable intensity
1 enable blinking

AL = 07 read palette register (PS/2)


BL = palette register to read (0-15)

on return:
BH = value of palette register

AL = 08 read border color (overscan register, PS/2)

on return:
BH = value of border color (overscan register)

AL = 09 read palette registers and border (PS/2)


ES:DX = pointer to 17 byte table representing 16 palette
registers and border color register
on return:
133

ES:DX = pointer to table provided as input

AL = 10 set DAC color register


BX = color register to set
CH = green value
CL = blue value
DH = red value

AL = 12 set block of DAC color registers


BX = first color register to set
CX = number of color registers to set
ES:DX = pointer to table of color values to set

AL = 13 set attribute controller color select state


BL = 0 set Mode Control register bit 7
BH = value for bit 7
BL = 1 set color select register
BH = value for color select register

AL = 15 read DAC color register (PS/2)


BX = color register to read

on return:
CH = green value
CL = blue value
DH = red value

AL = 17 read block of DAC color registers


BX = first color register to read
CX = number of color registers to read
ES:DX = pointer to buffer for color registers

on return:
ES:DX = pointer to color table provided as input

AL = 18 update video DAC mask register


BL = new mask

AL = 19 read video DAC mask register


134

on return:
BL = value read from video DAC mask register

AL = 1A read color page state


BL = bit 7 of Mode Control Register
BH = bits 2 thru 3 of Color select register if BL = 0
= bits 0 thru 3 of Color select register if BL = 1

on return:
BL = current paging mode
CX = current page

AL = 1B sum color values to shades of gray


BX = first color register to sum
CX = number of color registers to sum

- controls the pixel color mapping bit values


- BIOS extension to EGA/VGA systems

INT 10,11 - Character Generator Routine (EGA/VGA)

AH = 11h

AL = 00 user character load


BH = number of bytes per character
BL = table in character generator RAM
CX = count of characters in table
DX = ASCII code of first character defined
ES:BP = pointer to user table

AL = 01 ROM BIOS 8x14 monochrome set


BL = table in character generator RAM

AL = 02 ROM BIOS 8x8 double dot


BL = table in character generator RAM

AL = 03 set displayed definition table


BL = value for character Map Select register (EGA,VGA)
= character generator RAM table numbers (MCGA)
135

AL = 04 ROM BIOS 8x16 character set


BL = table in character generator RAM

AL = 10 user specified character definition table


BH = bytes per character (points)
BL = table in character generator RAM
CX = number of characters defined in table
DX = ASCII code of first character defined
ES:BP = pointer to user table

AL = 11 ROM BIOS 8x14 monochrome character set


BL = table in character generator RAM

AL = 12 ROM 8x8 double dot character definitions


BL = table in character generator RAM

AL = 14 ROM 8x16 double dot character definitions


BL = table in character generator RAM

AL = 20 pointer to graphics character table for ~INT 1F~ (8x8)


ES:BP = pointer to user table

AL = 21 user graphics character pointer at INT 43


BL = row specifier
= 0 - user specified (DL = rows)
= 1 is 14 rows
= 2 is 25 rows
= 3 is 43 rows
CX = bytes per character (points)
DL = rows (when BL = 0)
ES:BP = pointer to user table

AL = 22 ROM 8x14 character set


BL = number of rows (see AL=21)
DL = rows (when BL = 0)

AL = 23 ROM 8x8 double dot character set


BL = row specifier (see AL=21)
DL = rows (when BL = 0)

AL = 24 ROM 8x16 character set


136

BL = row specifier (see AL=21)


DL = rows (when BL = 0)

AL = 30 get current character generator information


BH = information desired:
= 0 ~INT 1F~ pointer
= 1 INT 44h pointer
= 2 ROM 8x14 pointer
= 3 ROM 8x8 double dot pointer (base)
= 4 ROM 8x8 double dot pointer (top)
= 5 ROM 9x14 alpha alternate pointer
= 6 ROM 8x16 character table pointer
= 7 ROM 9x16 alternate character table pointer

on return:
CX = bytes per character (points)
DL = rows (less 1)
ES:BP = pointer to table

INT 10,12 - Video Subsystem Configuration (EGA/VGA)

AH = 12h

BL = 10 return video configuration information

on return:
BH = 0 if color mode in effect
= 1 if mono mode in effect
BL = 0 if 64k EGA memory
= 1 if 128k EGA memory
= 2 if 192k EGA memory
= 3 if 256k EGA memory
CH = feature bits
CL = switch settings

BL = 20 select alternate print screen routine

BL = 30 select scan lines for alphanumeric modes


AL = 0 200 scan lines
= 1 350 scan lines
= 2 400 scan lines
137

on return:
AL = 12

BL = 31 select default palette loading


AL = 0 enable default palette loading
= 1 disable default palette loading

on return:
AL = 12

BL = 32 CPU access to video RAM


AL = 0 enable CPU access to video RAM and I/O ports
= 1 disable CPU access to video RAM and I/O ports

on return:
AL = 12

BL = 33 Gray scale summing


AL = 0 enable gray scale summing
= 2 disable gray scale summing

on return:
AL = 12

BL = 34 cursor emulation
AL = 0 enable cursor emulation
= 1 disable cursor emulation

on return:
AL = 12

BL = 35 PS/2 video display switching


AL = 0 initial adapter video off
= 1 initial planar video on
= 2 switch active video off
= 3 switch inactive video on
ES:DX pointer to 128 byte save area (when AL = 0, 2 or 3)
on return:
AL = 12
138

BL = 36 video refresh control


AL = 0 enable refresh
= 1 disable refresh

on return:
AL = 12

INT 10,13 - Write String (BIOS versions from 1/10/86)

AH = 13h
AL = write mode (see bit settings below)
= 0 string is chars only, attribute in BL, cursor not moved
= 1 string is chard only, attribute in BL, cursor moved
= 2 string contains chars and attributes, cursor not moved
= 3 string contains chars and attributes, cursor moved
BH = video page number
BL = attribute if mode 0 or 1 (AL bit 1=0)
CX = length of string (ignoring attributes)
DH = row coordinate
DL = column coordinate
ES:BP = pointer to string

returns nothing

- BEL, BS, CR, LF are treated as ASCII control codes


- wraps data and scrolls if unable to fit data on one line

INT 10,14 - Load LCD Character Font (convertible only)

AH = 14h

AL = 0 - load user specified font


ES:DI = pointer to character font
CX = number of characters to store
DX = char offset into ram font area
BH = number of bytes per character
BL = 0 load main font (block 0)
= 1 load alternate font (block 1)

AL = 1 - load system ROM default font


BL = 0 load main font (block 0)
139

= 1 load alternate font (block 1)

AL = 2 - set mapping of LCD high intensity attribute


BL = 0 ignore high intensity attribute
= 1 map high intensity to underscore
= 2 map high intensity to reverse video
= 3 map high intensity to select alternate font

INT 10,15 - Return Physical Display Parms (convertible)

AH = 15h

on return:
AX = alternate display adapter type
ES:DI = pointer to parameter table:

Offset Size Description

01 word monitor model number


02 word vertical pels per meter
03 word horizontal pels per meter
04 word total number of vertical pels
05 word total number of horizontal pels
06 word horizontal pel separation in micrometers
07 word vertical pel separation in micrometers

INT 10,1A - Video Display Combination (VGA)

AH = 1A
AL = 00 get video display combination
= 01 set video display combination
BL = active display (see table below)
BH = inactive display

on return:
AL = 1A, if a valid function was requested in AH
BL = active display (AL=00, see table below)
BH = inactive display (AL=00)

Valid display codes:


140

FF Unrecognized video system


00 No display
01 MDA with monochrome display
02 CGA with color display
03 Reserved
04 EGA with color display
05 EGA with monochrome display
06 Professional graphics controller
07 VGA with analog monochrome display
08 VGA with analog color display
09 Reserved
0A MCGA with digital color display
0B MCGA with analog monochrome display
0C MCGA with analog color display

- returns value at byte 40:8A indicating display combination


status
- used to detect video display capabilities

INT 10,1C - Save/Restore Video State (VGA only)

AH = 1C

AL = 0 get save buffer size


CX = requested states
bit 0: video hardware state
bit 1: video BIOS data areas
bit 2: video DAC state

on return:
AL = 1C
BX = buffer size in 64 byte blocks

AL = 1 save requested state


CX = requested states (see AL = 0)
ES:BX = pointer to buffer

returns nothing
141

AL = 2 restore requested states


CX = requested states (see AL = 0)
ES:BX = pointer to buffer

returns nothing

- returns data stored at ~BIOS Data Area~ location 40:10


- some flags are not guaranteed to be correct on all machines
- bit 13 is used on the PCjr to indicate serial printer

INT 12 - Memory Size Determination

no input data

on return:
AX = the number of contiguous 1k memory blocks found at
startup

- contiguous memory does not include video memory or extended


RAM

INT 14 - BIOS Asynchronous Communications


Services

Έλεγχος των σειριακών θυρών. Υπάρχουν οι εξής ρουτίνες:

INT 14,0 Initialize serial port parameters


INT 14,1 Send character in AL
INT 14,2 Receive character in AL
INT 14,3 Get Serial port status
INT 14,4 Extended initialize (PS/2)
INT 14,5 Extended communication port control (PS/2)

- all functions have:


AH = function number
AL = character to send or receive
DX = zero based RS232 card number
142

- all registers are preserved except AX


- these functions use hardware flow control
- used by DOS MODE to redirect LPTx output to a serial device
- see individual functions for more data

INT 16 - Keyboard BIOS Services

Ρουτίνες ανάγνωσης του πληκτρολογίου και της καταστάσεώς του.


Αναλυτικά, είναι οι εξής: (ο αριθμός της συνάρτησης δίνεται από τον
ΑΗ).

INT 16,0 Wait for keystroke and read


INT 16,1 Get keystroke status
INT 16,2 Get shift status
INT 16,3 Set keyboard typematic rate (AT+)
INT 16,4 Keyboard click adjustment (AT+)
INT 16,5 Keyboard buffer write (AT,PS/2 enhanced keyboards)
INT 16,10 Wait for keystroke and read (AT,PS/2 enhanced
keyboards)
INT 16,11 Get keystroke status (AT,PS/2 enhanced keyboards)
INT 16,12 Get shift status (AT,PS/2 enhanced keyboards)

- with IBM BIOS's, INT 16 functions do not restore the flags to


the pre-interrupt state to allow returning of information via
the flags register
- functions 3 through 12h are not available on all AT machines
unless the extended keyboard BIOS is present
- all registers are preserved except AX and FLAGS

INT 16,0 - Wait for Keypress and Read Character

AH = 00

on return:
AH = keyboard scan code
AL = ASCII character or zero if special function key
143

- halts program until key with a scancode is pressed

INT 16,1 - Get Keyboard Status

AH = 01

on return:
ZF = 0 if a key pressed (even Ctrl-Break)
AX = 0 if no scan code is available
AH = ~scan code~
AL = ASCII character or zero if special function key

- data code is not removed from buffer


- ~Ctrl-Break~ places a zero word in the keyboard buffer but
does register a keypress.

INT 16,2 - Read Keyboard Flags

AH = 02

on return:
AL = BIOS keyboard flags (located in ~BIOS Data Area~ 40:17)

Τα bits του AL ή του BIOS Data Area 40:17 έχουν ως εξής:

bit0: right shift key depressed


bit1: left shift key depressed
bit2: CTRL key depressed
bit3: ALT key depressed
bit4: scroll-lock is active
bit5: num-lock is active
bit6: caps-lock is active
bit7: insert is active

INT 16,3 - Set Keyboard Typematic Rate (AT+)

AH = 03
AL = 00 set typematic rate to default
144

01 increase initial delay


02 slow typematic rate by 1/2
04 turn off typematic chars
05 set typematic rate/delay

BH = repeat delay (AL=5)


0 = 250ms 2 = 750ms
1 = 500ms 3 = 1000ms

BL = typematic rate, one of the following (AL=5)

00 - 30.0 01 - 26.7 02 - 24.0 03 - 21.8


04 - 20.0 05 - 18.5 06 - 17.1 07 - 16.0
08 - 15.0 09 - 13.3 0A - 12.0 0B - 10.9
0C - 10.0 0D - 9.2 0E - 8.6 0F - 8.0
10 - 7.5 11 - 6.7 12 - 6.0 13 - 5.5
14 - 5.0 15 - 4.6 16 - 4.3 17 - 4.0
18 - 3.7 19 - 3.3 1A - 3.0 1B - 2.7
1C - 2.5 1D - 2.3 1E - 2.1 1F - 2.0

returns nothing

- if the typematic rate is not within range,no action is taken


- available on AT and PS/2 machines with extended keyboard
support

INT 16,4 - Keyboard Click Adjustment (AT+)

AH = 04
AL = 1 for click on
= 0 for click off

- available only on AT and later machines that support the


extended keyboard BIOS

INT 16,5 - Keyboard Buffer Write (AT+)

AH = 05
CH = ~scan code~
CL = ASCII character
145

on return:
AL = 00 if success
01 if buffer full

- available on AT and PS/2 machines with extended keyboard


support
- stores normal keystroke into keyboard buffer
- will not store attribute keys like Shift, Alt, Ctrl, etc...

INT 16,10 - Extended Wait for Keypress and Read Character (AT+)

AH = 10h

on return:
AH = ~scan code~
AL = ASCII character or zero if special function key

- available on AT and PS/2 machines with extended keyboard


support
- similar to ~INT 16,0~

INT 16,11 - Extended Get Keyboard Status (AT+)

AH = 11h

on return:
ZF = 0 if key pressed (data waiting)
AX = 0 if no scan code is available
AH = ~scan code~
AL = ASCII character or zero if special function key

- available on AT and PS/2 machines with extended keyboard


support
- data is not removed from buffer
- similar to ~INT 16,1~

INT 16,12 - Extended Get Keyboard Status (AT+)

AH = 12h

on return:
146

AH = BIOS keyboard flags (~BIOS Data Area~ location 40:18)

bit0: left CTRL key depressed


bit1: left ALT key depressed
bit2: right CTRL key pressed
bit3: right ALT key depressed
bit4: scroll-lock depressed
bit5: num-lock key depressed
bit6: caps-lock key depressed
bit7: system request key depressed

AL = BIOS keyboard flags (BIOS Data Area location 40:17)-

bit0: right shift key depressed


bit1: left shift key depressed
bit2: CTRL key depressed
bit3: ALT key depressed
bit4: scroll-lock is active
bit5: num-lock is active
bit6: caps-lock is active
bit7: insert is active

INT 21 - Συναρτήσεις DOS

Οι συναρτήσεις του DOS είναι συνολικά οι εξής:

~INT 21,0~ Program terminate


~INT 21,1~ Keyboard input with echo
~INT 21,2~ Display output
~INT 21,3~ Wait for auxiliary device input
~INT 21,4~ Auxiliary output
~INT 21,5~ Printer output
~INT 21,6~ Direct console I/O
~INT 21,7~ Wait for direct console input without echo
~INT 21,8~ Wait for console input without echo
~INT 21,9~ Print string
~INT 21,A~ Buffered keyboard input
~INT 21,B~ Check standard input status
~INT 21,C~ Clear keyboard buffer, invoke keyboard function
147

~INT 21,D~ Disk reset


~INT 21,E~ Select disk
~INT 21,F~ Open file using FCB
~INT 21,10~ Close file using FCB
~INT 21,11~ Search for first entry using FCB
~INT 21,12~ Search for next entry using FCB
~INT 21,13~ Delete file using FCB
~INT 21,14~ Sequential read using FCB
~INT 21,15~ Sequential write using FCB
~INT 21,16~ Create a file using FCB
~INT 21,17~ Rename file using FCB
~INT 21,18~ DOS dummy function (CP/M) (not used/listed)
~INT 21,19~ Get current default drive
~INT 21,1A~ Set disk transfer address
~INT 21,1B~ Get allocation table information
~INT 21,1C~ Get allocation table info for specific device
~INT 21,1D~ DOS dummy function (CP/M) (not used/listed)
~INT 21,1E~ DOS dummy function (CP/M) (not used/listed)
~INT 21,1F~ Get pointer to default drive parameter table
~INT 21,20~ DOS dummy function (CP/M) (not used/listed)
~INT 21,21~ Random read using ~FCB~
~INT 21,22~ Random write using FCB
~INT 21,23~ Get file size using FCB
~INT 21,24~ Set relative record field for FCB
~INT 21,25~ Set interrupt vector
~INT 21,26~ Create new program segment
~INT 21,27~ Random block read using FCB
~INT 21,28~ Random block write using FCB
~INT 21,29~ Parse filename for FCB
~INT 21,2A~ Get date
~INT 21,2B~ Set date
~INT 21,2C~ Get time
~INT 21,2D~ Set time
~INT 21,2E~ Set/reset verify switch
~INT 21,2F~ Get disk transfer address
~INT 21,30~ Get DOS version number
~INT 21,31~ Terminate process and remain resident
~INT 21,32~ Get pointer to drive parameter table
~INT 21,33~ Get/set ~Ctrl-Break~ check state & get boot drive
~INT 21,34~ Get address to DOS critical flag (undocumented)
~INT 21,35~ Get vector
148

~INT 21,36~ Get disk free space


~INT 21,37~ Get/set switch character (undocumented)
~INT 21,38~ Get/set country dependent information
~INT 21,39~ Create subdirectory (mkdir)
~INT 21,3A~ Remove subdirectory (rmdir)
~INT 21,3B~ Change current subdirectory (chdir)
~INT 21,3C~ Create file using handle
~INT 21,3D~ Open file using handle
~INT 21,3E~ Close file using handle
~INT 21,3F~ Read file or device using handle
~INT 21,40~ Write file or device using handle
~INT 21,41~ Delete file
~INT 21,42~ Move file pointer using handle
~INT 21,43~ Change file mode
~INT 21,44~ I/O control for devices (~IOCTL~)
~INT 21,45~ Duplicate file handle
~INT 21,46~ Force duplicate file handle
~INT 21,47~ Get current directory
~INT 21,48~ Allocate memory blocks
~INT 21,49~ Free allocated memory blocks
~INT 21,4A~ Modify allocated memory blocks
~INT 21,4B~ EXEC load and execute program
~INT 21,4C~ Terminate process with return code
~INT 21,4D~ Get return code of a sub-process
~INT 21,4E~ Find first matching file
~INT 21,4F~ Find next matching file
~INT 21,50~ Set current process id (undocumented)
~INT 21,51~ Get current process id (undocumented)
~INT 21,52~ Get pointer to DOS "INVARS" (undocumented)
~INT 21,53~ Generate drive parameter table (undocumented)
~INT 21,54~ Get verify setting
~INT 21,55~ Create ~PSP~ (undocumented)
~INT 21,56~ Rename file
~INT 21,57~ Get/set file date and time using handle
~INT 21,58~ Get/set memory allocation strategy
~INT 21,59~ Get extended error information (3.x+)
~INT 21,5A~ Create temporary file (3.x+)
~INT 21,5B~ Create new file (3.x+)
~INT 21,5C~ Lock/unlock file access (3.x+)
~INT 21,5D~ Critical error information (undocumented 3.x+)
~INT 21,5E~ Network services (3.1+)
149

~INT 21,5F~ Network redirection (3.1+)


~INT 21,60~ Get fully qualified file name (undocumented 3.x+)
~INT 21,62~ Get address of program segment prefix (3.x+)
~INT 21,63~ Get system lead byte table (MSDOS 2.25 only)
~INT 21,64~ Set device driver look ahead (undocumented 3.3+)
~INT 21,65~ Get extended country information (3.3+)
~INT 21,66~ Get/set global code page (3.3+)
~INT 21,67~ Set handle count (3.3+)
~INT 21,68~ Flush buffer (3.3+)
~INT 21,69~ Get/set disk serial number (undocumented DOS 4.0+)
~INT 21,6A~ DOS reserved (DOS 4.0+)
~INT 21,6B~ DOS reserved
~INT 21,6C~ Extended open/create (4.x+)
~INT 21,F8~ Set OEM INT 21 handler (functions F9-FF)

- int 21 functions are called with the function number in AH


- register AX may be altered, its contents are not guaranteed
- if an error occurs, CF is set to 1 and AX contains a simple
error code; ~INT 21,59~ can be used to determine cause.
- most INT 21 functions do not restore the flags to pre-
interrupt state to allow returning of information via the flags
register

INT 21,0 - Program Terminate

AH = 00
CS = PSP segment address

returns nothing

- restores the terminate, ~Ctrl-Break~, and critical error


exit addresses, flushes all buffers, frees memory
and returns to DOS via the termination handler address
- does not close ~FCB~s
- this function is no longer recommended, but can be used by
version of DOS before 2.0
150

INT 21,1 - Keyboard Input with Echo

AH = 01

on return:
AL = character from standard input device

- waits for keyboard input from STDIN and echoes to STDOUT


- returns 0 for extended keystroke, then function must be
called again to return scan code
- if ~Ctrl-Break~ is detected, ~INT 23~ is executed

INT 21,2 - Display Output

AH = 02
DL = character to output

returns nothing

- outputs character to STDOUT


- backspace is treated as non-destructive cursor left
- if ~Ctrl-Break~ is detected, ~INT 23~ is executed

INT 21,3 - Wait for Auxiliary Device Input

AH = 03

on return:
AL = character from the auxiliary device

- does not supply error returns


- waits for character and reads from STDAUX
- default DOS AUX parameters are 2400,N,8,1

INT 21,4 - Auxiliary Output

AH = 04
DL = character to output

returns nothing
151

- sends character in DL to STDAUX


- does not supply error returns
- waits until STDAUX is available
- default DOS AUX parameters are 2400,N,8,1

INT 21,5 - Printer Output

AH = 05
DL = character to output

returns nothing

- sends character in DL to STDPRN


- waits until STDPRN device is ready before output

INT 21,6 - Direct Console I/O

AH = 06
DL = (0-FE) character to output
= FF if console input request

on return:
AL = input character if console input request (DL=FF)
ZF = 0 if console request character available (in AL)
= 1 if no character is ready, and function request
was console input:

- reads from or writes to the console device depending on


the value of DL
- cannot output character FF (DL=FF indicates read function)
- for console read, no echo is produced
- returns 0 for extended keystroke, then function must be
called again to return scan code
- ignores Ctrl-Break and Ctrl-PrtSc

INT 21,7 - Direct Console Input Without Echo

AH = 07

on return:
AL = character from STDIN
152

- waits for keyboard input until keystroke is ready


- character is not echoed to STDOUT
- returns 0 for extended keystroke, then function must be
called again to return scan code
- ignores Ctrl-Break and Ctrl-PrtSc

INT 21,8 - Console Input Without Echo

AH = 08

on return:
AL = character from STDIN

- returns 0 for extended keystroke, then function must be


called again to return scan code
- waits for character from STDIN and returns data in AL
- if ~Ctrl-Break~ is detected, ~INT 23~ is executed

INT 21,9 - Print String

AH = 09
DS:DX = pointer to string ending in "$"

returns nothing

- outputs character string to STDOUT up to "$"


- backspace is treated as non-destructive
- if ~Ctrl-Break~ is detected, ~INT 23~ is executed

INT 21,A - Buffered Keyboard Input

AH = 0A
DS:DX = pointer to input buffer

INT 21,B - Check Standard Input Status

AH = 0B

on return:
AL = 00 if no character available
153

= FF if character available

- checks STDIN for available characters


- character is not returned
- if Ctrl-Break is detected ~INT 23~ is executed

INT 21,C - Clear Keyboard Buffer and Invoke Keyboard Function

AH = 0C
AL = 01, 06, 07, 08 or 0A (INT 21 input functions)

on return:
see return values from INT 21,AL where AL is 1, 6, 7, 8 or A

- main function is to clear the input buffer and call INT 21h
with the specified function (in AL)

INT 21,D - Disk Reset

AH = 0D

returns nothing

- all file buffers are flushed to disk


- does NOT update directory entry

INT 21,E - Select Disk

AH = 0E
DL = zero based, drive number (0-25, A: - Z:)

on return:
AL = one based, total number of logical drives including
hardfiles (1-26)

- for DOS 3.x+, this function returns the number of logical


drives or the value of LASTDRIVE (default of 5) in the
CONFIG.SYS file
154

INT 21,F - Open a File Using FCB

AH = 0F
DS:DX = pointer to unopened FCB

on return:
AL = 00 if file opened
= FF if unable to open

- opens an existing file using a previously setup FCB


- the FCB fields drive identifier, filename and extension
must be filled in before call
- sets default FCB fields; current block number is set to 0;
record size is set to 80h; file size, date and time are set
to the values from the directory
- does not create file, see ~INT 21,16~
- DOS 2.x allows opening of subdirectories, DOS 3.x does not

INT 21,10 - Close a File Using FCB

AH = 10h
DS:DX = pointer to opened ~FCB~

on return:
AL = 00 if file closed
= FF if file not closed

- closes a previously opened file opened with an FCB


- FCB must be setup with drive id, filename, and extension
before call

INT 21,11 - Search for First Entry Using FCB

AH = 11h
DS:DX = pointer to unopened ~FCB~

on return:
AL = 00 if matching file found
= FF if file not found

- searches for first occurrence of filename specified in FCB


155

- FCB must have drive id, filename, and extension before call
- extended FCB can be used to specify a search criteria based
on attributes; hidden, system, label, and directory
attributes can be used to narrow the search
- after successful call DTA holds an unopened ~FCB~/~XFCB~ for
the requested file. Using any of the other FCB functions
destroys this ~DTA~ copy of the FCB/XFCB
- searching can be continued with the FCB find-next function
- "?" wildcard supported after DOS 2.1, "*" supported in DOS
3.x
- DOS 2.x can't find . and .. entries, DOS 3.x can (unless in
root)

INT 21,12 - Search for Next Entry Using FCB

AH = 12h
DS:DX = pointer to unopened ~FCB~ returned from
~INT 21,11~ or ~INT 21,12~

on return:
AL = 00 if file found
= FF if file not found

- finds next matching file after calls to ~INT 21,11~ and


~INT 21,12~
- FCB should be the same across calls to INT 21,11 and 12
- after successful call ~DTA~ holds an unopened ~FCB~/~XFCB~
for
the requested file. Using any of the other FCB functions
destroys this DTA copy of the FCB/XFCB

INT 21,13 - Delete File Using FCB

AH = 13h
DS:DX = pointer to an unopened ~FCB~

on return:
AL = 00 if file deleted
= FF if file not found

- deletes unopened file with normal attributes


156

- FCB must contain drive id, filename, and extension before


call
- "?" wildcard supported after DOS 2.1, "*" supported by DOS
3.x+
- DOS 2.x allowed deletion of a subdirectory if ~XFCB~ was
provided, even if files existed, causing lost clusters.

INT 21,14 - Sequential Read Using FCB

AH = 14h
DS:DX = pointer to an opened ~FCB~

on return:
AL = 00 if successful read
= 01 if end of file (no data read)
= 02 if ~DTA~ is too small
= 03 if end of file or partial record read

- reads a record from file pointed to by FCB at the location


specified in current block and current record number
- data record is read into the DTA
- FCB record number is updated

INT 21,15 - Sequential Write Using FCB

AH = 15h
DS:DX = pointer to an opened ~FCB~

on return:
AL = 00 if write was successful
= 01 if diskette is full or read only
= 02 if ~DTA~ is too small

- writes a record from the DTA to the current record position


in file specified by the opened FCB
- record size and output location are maintained in the FCB

INT 21,16 - Create a File Using FCB

AH = 16h
DS:DX = pointer to an unopened ~FCB~
157

on return:
AL = 00 if file created
= FF if file creation failed

- creates file using FCB and leaves open for later output
- FCB must be setup with drive id, filename, and extension
before call

INT 21,17 - Rename a File Using FCB

AH = 17h
DS:DX = pointer to a modified ~FCB~ of the format:

Offset Description
00 drive designator
01 original file name
09 original file extension
11 new file name
19 new extension

on return:
AL = 00 if file renamed
= FF if file not renamed

- allows renaming of files with normal attributes


- "?" wildcard supported after DOS 2.1, "*" supported by
DOS 3.x+

INT 21,19 - Get Current Default Drive

AH = 19h

on return:
AL = current default drive (0=A,1=B,etc)

- determines the current default drive

INT 21,1A - Set Disk Transfer Address (DTA)

AH = 1A
158

DS:DX = pointer to disk transfer address (~DTA~)

returns nothing

- specifies the disk transfer address to DOS


- DTA cannot overlap 64K segment boundary
- offset 80h in the ~PSP~ is a 128 byte default DTA supplied
by DOS upon program load
- use of the DTA provided by DOS will result in the loss
of the program command tail which also occupies the 128
bytes starting at offset 80h of the PSP

INT 21,1B - Get Allocation Table Information

AH = 1B

on return:
AL = sectors per cluster
CX = bytes per sector
DX = clusters on disk
DS:BX = pointer to ~Media Descriptor Byte~ found in ~FAT~

- retrieves information on capacity and format of default drive


- DS:BX can be used to determine if drive is RAMDISK or
removable

INT 21,1C - Get Allocation Table Info for Specified Drive

AH = 1C
DL = drive number (0 for default, 1 = A:, Z: = 26)

on return:
AL = sectors per cluster
CX = bytes per sector
DX = clusters on disk
DS:BX = pointer to ~Media Descriptor Byte~ found in ~FAT~

- retrieves information on capacity and format of specified


drive
- DS:BX can be used to determine if drive is RAMDISK or
removable
159

INT 21,21 - Random Read Using FCB

AH = 21h
DS:DX = pointer to an opened ~FCB~

on return:
AL = 00 if read successful
= 01 if EOF (no data read)
= 02 if ~DTA~ is too small
= 03 if EOF (partial record read)

- reads random records from a file opened with an FCB


to the DTA
- FCB must be setup with drive id, filename, extension,
record position and record length before call
- current record position field in FCB is not updated

INT 21,22 - Random Write Using FCB

AH = 22h
DS:DX = far pointer to an opened ~FCB~

on return:
AL = 00 if write successful
= 01 if diskette full or read only
= 02 if ~DTA~ is too small

- write records to random location in file opened with FCB


- FCB must be setup with drive id, filename, extension,
record position and record length before call
- current record position field in FCB is not updated

INT 21,23 - Get File Size Using FCB

AH = 23h
DS:DX = pointer to an unopened ~FCB~

on return:
AL = 00 if successful
160

= FF if file not found

- determines the number of records in a file


- FCB must be setup with drive id, complete filename and
extension plus record length before call
- updates random record position in FCB located at DS:DX
with file record count

INT 21,24 - Set Relative Record Field in FCB

AH = 24h
DS:DX = pointer to an opened ~FCB~

returns nothing

- modifies opened FCB for random operation


- sets FCB random record field to current sequential block
and record fields

INT 21,25 - Set Interrupt Vector

AH = 25h
AL = interrupt number
DS:DX = pointer to interrupt handler

returns nothing

INT 21,26 - Create New Program Segment Prefix

AH = 26h
DX = segment address of new ~PSP~

returns nothing

- allocates memory for a PSP and copies current PSP there


- the application is responsible for allocating any memory
necessary for the child process
- ~INT 21,4B~ (EXEC) is now the recommended method for starting
a child process, so this function should be avoided
161

INT 21,27 - Random Block Read Using FCB

AH = 27h
CX = number of records to read
DS:DX = pointer to an opened ~FCB~

on return:
AL = 00 if read was successful
= 01 if EOF (no data read)
= 02 if ~DTA~ is too small
= 03 if EOF (partial record read)
CX = actual number of records read

- allows random access and sequential reading of a group


of records from a file opened with an FCB into the DTA
- FCB must be setup with drive id, filename, extension
record length and random record number before call

INT 21,28 - Random Block Write Using FCB

AH = 28h
CX = number of records to write
DS:DX = pointer to an opened ~FCB~

on return:
AL = 00 if write successful
= 01 if diskette full or read only
= 02 if ~DTA~ is too small
CX = number of records written

- allows random access and sequential writing of a group


of records from a file opened with an FCB into the DTA
- FCB must be setup with random record number and record size
- updates random record number, current block and current
record fields

INT 21,2A - Get Date

AH = 2A

on return:
162

AL = day of the week (0=Sunday)


CX = year (1980-2099)
DH = month (1-12)
DL = day (1-31)

- retrieves system date based on the DOS maintained clock


- updates ~BIOS Data Area~ current date and date rollover flag
at location 40:70

INT 21,2B - Set Date

AH = 2B
CX = year (1980-2099)
DH = month (1-12)
DL = day (1-31)

on return:
AL = 00 if date change successful
= FF if invalid date

- sets DOS maintained clock


- DOS versions 3.3+ also update the ~CMOS~ date where
applicable

INT 21,2C - Get Time

AH = 2C

on return:
CH = hour (0-23)
CL = minutes (0-59)
DH = seconds (0-59)
DL = hundredths (0-99)

- retrieves DOS maintained clock time

INT 21,2D - Set Time

AH = 2D
CH = hour (0-23)
CL = minutes (0-59)
163

DH = seconds (0-59)
DL = hundredths (0-99)

on return:
AL = 00 if time change successful
= FF if time invalid

- changes DOS maintained clock


- DOS version 3.3+ also update CMOS clock where applicable

INT 21,2F - Get Disk Transfer Address (DTA)

AH = 2F

on return:
ES:BX = pointer to current ~DTA~

- returns the DTA address


- the default DTA is a 128 byte block at address 80h in the
Program Segment Prefix (~PSP~). This area also contains the
command tail at program startup it must be saved or the DTA
must be relocated before use to preserve the command tail

INT 21,30 - Get DOS Version Number

AH = 30h

on return:
AL = major version number (2-5)
AH = minor version number (in hundredths decimal)
BH = FF indicates MS-DOS, only if OEM vendor chooses to
identify
= 00 indicates PC-DOS
BL:CX = 24 bit OEM serial number if BH is FF

- for an example DOS version 2.1 returns AL=2 and AH=10

INT 21,31 - Terminate Process and Remain Resident

AH = 31h
164

AL = exit code (returned to batch files)


DX = memory size in paragraphs to reserve

returns nothing

- preferred method for Terminate and Stay Resident programs


- terminates process without releasing allocated memory and
without closing open files
- attempts allocation of memory specified in DX from memory
allocated by DOS at startup.

INT 21,33 - Get/Set System Values (Ctl-Break/Boot Drive)

AH = 33h
AL = 00 to get Ctrl-Break checking flag
= 01 to set Ctrl-Break checking flag
= 02 to set extended Ctrl-Break checking
= 05 get boot drive (DOS 4.x)
DL = 00 to set Ctrl-Break checking off
= 01 to set Ctrl-Break checking on
= boot drive for subfunction 5; (1=A:, 2=B:, ...)

on return:
DL = 00 Ctrl-Break checking OFF (AL=0 or AL=2)
= 01 Ctrl-Break checking ON (AL=0 or AL=2)
= boot drive number (1-26, A: - Z:) (function 05)

- retrieves DOS Ctrl-Break or extended Ctrl-Break setting which


determines if DOS will check for Ctrl-Break during INT 21
calls

INT 21,35 - Get Interrupt Vector

AH = 35h
AL = interrupt vector number

on return:
ES:BX = pointer to interrupt handler

- standard method for retrieving interrupt vectors


165

INT 21,36 - Get Disk Free Space

AH = 36h
DL = drive number (0=default, 1=A:)

on return:
AX = sectors per cluster
= FFFF if drive is invalid
BX = number of available clusters
CX = number of bytes per sector
DX = number of clusters per drive

- used to determine available space on specified disk

INT 21,39 - Create Subdirectory (mkdir)

AH = 39h
DS:DX = pointer to ASCIIZ path name

on return:
CF = 0 if successful
= 1 if error
AX = error code
- creates specified subdirectory
- returns error if directory already exists, element of the
path is not found, directory full or write protected disk

INT 21,3A - Remove Subdirectory (rmdir)

AH = 3A
DS:DX = pointer to ASCIIZ path name

on return:
CF = 0 if successful
= 1 if error
AX = error code
- allows deletion of a subdirectory as long as it exists, is
empty and not the current directory
166

INT 21,3B - Change Current Directory (chdir)

AH = 3B
DS:DX = pointer to ASCIIZ path name

on return:
CF = 0 if successful
= 1 if error
AX = error code if CF set

- changes the current directory to the directory specified


by pointer DS:DX

INT 21,3C - Create File Using Handle

AH = 3C
CX = file attribute
DS:DX = pointer to ASCIIZ path name

on return:
CF = 0 if successful
= 1 if error
AX = files handle if successful
= error code if failure

- if file already exists, it is truncated to zero bytes on


opening

INT 21,3D - Open File Using Handle

AH = 3D
AL = open access mode
00 read only
01 write only
02 read/write
DS:DX = pointer to an ASCIIZ file name

on return:
AX = file handle if CF not set
= error code if CF set
167

- will open normal, hidden and system files


- file pointer is placed at beginning of file

INT 21,3E - Close File Using Handle

AH = 3E
BX = file handle to close

on return:
AX = error code if CF set
- if file is opened for update, file time and date stamp
as well as file size are updated in the directory
- handle is freed

INT 21,3F - Read From File or Device Using Handle

AH = 3F
BX = file handle
CX = number of bytes to read
DS:DX = pointer to read buffer

on return:
AX = number of bytes read is CF not set
= error code if CF set
- read specified number of bytes from file into buffer DS:DX
- when AX is not equal to CX then a partial read occurred due
to end of file
- if AX is zero, no data was read, and EOF occurred before read

INT 21,40 - Write To File or Device Using Handle

AH = 40h
BX = file handle
CX = number of bytes to write, a zero value truncates/extends
the file to the current file position
DS:DX = pointer to write buffer

on return:
AX = number of bytes written if CF not set
= error code if CF set
168

- if AX is not equal to CX on return, a partial write occurred


- this function can be used to truncate a file to the current
file position by writing zero bytes

INT 21,41 - Delete File

AH = 41h
DS:DX = pointer to an ASCIIZ filename

on return:
AX = error code if CF set

- marks first byte of file directory entry with E5 to indicate


the file has been deleted. The rest of the directory entry
stays intact until reused. ~FAT~ pointers are returned to
DOS
- documented as not accepting wildcards in filename but
actually does in several DOS versions

INT 21,42 - Move File Pointer Using Handle

AH = 42h
AL = origin of move:
00 = beginning of file plus offset
01 = current location plus offset
02 = end of file plus offset
BX = file handle
CX = high order word of number of bytes to move
DX = low order word of number of bytes to move

on return:
AX = error code if CF set
DX:AX = new pointer location if CF not set

- seeks to specified location in file

INT 21,43 - Get/Set File Attributes

AH = 43h
AL = 00 to get attribute
= 01 to set attribute
169

DS:DX = pointer to an ASCIIZ path name


CX = attribute to set
on return:
AX = error code if CF set
CX = the attribute if AL was 00

INT 21,44 - I/O Control for Devices (IOCTL)

Standard Call Format

AH = 44h
AL = function value
BX = file handle
BL = logical device number (0=default, 1=A:, 2=B:, 3=C:, ...)
CX = number of bytes to read or write
DS:DX = data or buffer

on return:
AX = error code if CF set
AX = # of bytes transferred if CF not set

~IOCTL,0~ Get Device Information


~IOCTL,1~ Set Device Information
~IOCTL,2~ Read From Character Device
~IOCTL,3~ Write to Character Device
~IOCTL,4~ Read From Block Device
~IOCTL,5~ Write to Block Device
~IOCTL,6~ Get Input Status
~IOCTL,7~ Get Output Status
~IOCTL,8~ Device Removable Query
~IOCTL,9~ Device Local or Remote Query
~IOCTL,A~ Handle Local or Remote Query
~IOCTL,B~ Set Sharing Retry Count
~IOCTL,C~ Generic I/O for Handles
~IOCTL,D~ Generic I/O for Block Devices (3.2+)
~IOCTL,E~ Get Logical Drive (3.2+)
~IOCTL,F~ Set Logical Drive (3.2+)

όπου η υποσυνάρτηση υπάρχει στον AL.

on return
170

AX = error code if CF set (see ~DOS ERROR CODES~)

- provides device independent primitive control operations


- implemented from DOS 3.2

INT 21,47 - Get Current Directory

AH = 47h
DL = drive number (0 = default, 1 = A:)
DS:SI = pointer to a 64 byte user buffer

on return:
DS:SI = pointer ASCIIZ directory path string
AX = error code if CF set

- returns the current directory relative to the root directory


- the leading slash "\" and drive designator are omitted

INT 21,48 - Allocate Memory

AH = 48h
BX = number of memory paragraphs requested

on return:
AX = segment address of allocated memory block (MCB + 1para)
= error code if CF set
BX = size in paras of the largest block of memory available
if CF set, and AX = 08 (Not Enough Mem)
CF = 0 if successful
= 1 if error

- returns segment address of allocated memory block AX:0000


- each allocation requires a 16 byte overhead for the ~MCB~
- returns maximum block size available if error

INT 21,49 - Free Allocated Memory

AH = 49h
ES = segment of the block to be returned (~MCB~ + 1para)

on return:
171

AX = error code if CF set

- releases memory and MCB allocated by ~INT 21,48~


- may cause unpredictable results is memory wasn't allocated
using INT 21,48 or if memory wasn't allocated by the current process
- checks for valid MCB id, but does NOT check for process
ownership
- care must be taken when freeing the memory of another
process, to assure the segment isn't in use by a TSR or ISR
- this function is unreliable in a TSR once resident, since
COMMAND.COM and many other .COM files take all available memory
when they load

INT 21,4A - Modify Allocated Memory Block (SETBLOCK)

AH = 4A
BX = new requested block size in paragraphs
ES = segment of the block (~MCB~ + 1 para)

on return:
AX = error code if CF set (see ~DOS ERROR CODES~)
BX = maximum block size possible, if CF set and AX = 8

- modifies memory blocks allocated by ~INT 21,48~


- can be used by programs to shrink or increase the size
of allocated memory

INT 21,4B - EXEC/Load and Execute Program

AH = 4B
AL = 00 to load and execute program
= 01 (Undocumented) create program segment prefix and load
program, but don't execute. The CS:IP and SS:SP of the
program is placed in parameter block. Used by debuggers
= 03 load program only
= 04 called by MSC spawn() when P_NOWAIT is specified
DS:DX = pointer to an ASCIIZ filename
ES:BX = pointer to a parameter block

on return:
AX = error code if CF set
172

ES:BX = when AL=1, pointer to parameter block similar to:

Offset Size Description

00 word when AL=1, segment of env. or zero if using


parents env.
word when AL=3, segment of load point for overlay
02 dword when AL=1, pointer to cmd line at PSP 80h
word when AL=3, relocation factor for EXE overlay
06 dword pointer to default ~FCB~ passed at ~PSP~ 5Ch
0A dword pointer to default FCB passes at PSP 6Ch
0E dword value of program SS:SP
12 dword value of program CS:IP

- allows execution of an external program as well as overlay


management from within an application
- all registers except CS and IP are destroyed
- SS and SP should be preserved in code segment before call
since a bug in DOS version 2.x destroys these
- return code can be retrieved if child process exits via ~INT
21,4C~
- calling process must assure presence of enough unallocated
memory
- subfunction 4 returns with an error under DOS 4.x+
- calls ~INT 21,55~

INT 21,4C - Terminate Process With Return Code

AH = 4C
AL = return code (for batch files)

returns nothing

- approved method of program termination


- restores the terminate, ~Ctrl-Break~, and critical error exit
addresses, flushes all buffers, frees memory and returns to
DOS via the termination handler address
- does not close FCBs
173

INT 21,4D - Get Return Code of Sub-process

AH = 4D

on return:
AH = system exit code (indicates normal termination)
= 00 for normal termination
= 01 if terminated by ctl-break
= 02 if critical device error
= 03 if terminated by ~INT 21,31~
AL = child exit code

- retrieve child process and system exit codes


- this function can only be used to retrieve the exit code once
multiple attempts to read exit codes will cause errors

INT 21,4E - Find First Matching File

AH = 4E
CX = attribute used during search DS:DX = pointer to ASCIIZ
filespec, including wildcards

on return:
AX = error code if CF set
~DTA~ = data returned from call in the format:

Offset Size Description

00 byte attribute of search (undocumented)


byte drive letter used in search (DOS 3.1-4.x,
undocumented)
01 byte drive letter used in search (undocumented)
11bytes search name used (DOS 3.1-4.x, undocumented)
02 11bytes search name used (undocumented)
0C byte attribute of search (DOS 3.1-4.x, undocumented)
0D word directory entry number (0 based, undocumented)
0F word starting cluster number of current directory;
zero for root directory (DOS 3.2+, undocumented)
dword pointer to DTA (DOS 2.x-3.1, undocumented)
11 word reserved
174

13 word starting cluster number of current directory;


zero for root directory (DOS 2.x+, undocumented)
15 byte attribute of matching file
16 word file time
18 word file date
1A word file size
1E 13bytes ASCIIZ filename and extension in the form
NAME.EXT with blanks stripped

- returns information on first file matching specifications


- use ~INT 21,4F~ to retrieve following file matches
- DOS 2.x cannot find . and .. entries, while DOS 3.x can
unless they represent the root directory
- character devices return a zero for size, time and date in
DOS 2.x, while DOS 3.0 returns a 40h attribute and current time and
date.
- multiple calls to this function with a character device will
result in unpredictable results
- normal files are always included along with files that match
the requested attributes except when the LABEL attribute is
requested. DOS 2.x returns all normal files when label is specified
but 3.x doesn't. It's up to the programmer to determine which
actually match the requested attributes.

INT 21,4F - Find Next Matching File

AH = 4F
DS:DX = unchanged from previous function 4E

on return:
AX = error code if CF set

- ~INT 21,4E~ should be called to find the first file and this
function should be called to find all other matching files
- normal files are always included along with files that match
the requested attributes except when the LABEL attribute is
requested. It's up to the programmer to determine which
actually match the requested attributes.
175

INT 21,50 - Set Current Process ID

AH = 50h
BX = process ID number (process ~PSP~ segment address)

returns nothing

- the process ID number is actually the segment address of a


program's PSP. This is useful for TSR's to access their own
file handle table inside their PSP.

INT 21,51 - Get Current Process ID

AH = 51h

on return:
BX = process ID

- The process ID number is actually the segment address of


program's PSP. This in conjunction with ~INT 21,50~ is useful for
TSR's to access their own file handle table in their respective
~PSP~.

INT 21,55 - Create New PSP (Undocumented)

AH = 55h
DX = New PSP segment address
SI = memory size value to place in ~PSP~ offset 02h (DOS 3+)

returns nothing

- the following should be observed when using this function

o Allocate memory for the PSP and program code (~INT


21,48~)
o Duplicate the PSP (~INT 21,55~)
o Load program code into allocated segment above the new PSP
o Save Current PSP
o Set PSP to the PSP just created (~INT 21,50~)
o Jump to start of code if .COM otherwise handle relocation,
setup stack and registers
176

- similar to ~INT 21,26~ except the PSP is setup by DOS


- increments reference count in ~SFT~ for all inherited files
- files flagged as not inheritable are marked as closed in the
new PSP
- invoked by ~INT 21,4B~

INT 21,56 - Rename File

AH = 56h
DS:DX = pointer to old ASCIIZ path/filename
ES:DI = pointer to new ASCIIZ path/filename

on return:
AX = error code if CF set

INT 21,59 - Get Extended Error Information (DOS 3.0+)

AH = 59h
BX = 00 for versions 3.0, 3.1, 3.2

on return:
AX = extended error code (see ~DOS ERROR CODES~)
= 0 if no error
BH = error class
BL = suggested action
CH = locus

- may be called after any ~INT 21~ function or from


~INT 24~ when an error is returned
- must be called immediately after the error occurs
- registers CX, DX, DI, SI, BP, DS and ES are destroyed

INT 21,5B - Create File (DOS 3.0+)

AH = 5B
CX = attribute
DS:DX = pointer to ASCIIZ path/filename

on return:
AX = handle if CF not set
177

= error code if CF set

- standard method of opening files


- returns a file handle of a file opened with specified
attributes (combinations of normal, system and hidden

INT 21,5E AL=02 Set Printer Setup (DOS 3.1+)

AH = 5E
AL = 02 set printer setup
BX = redirection list index (see ~INT 21,5F~ AL=2)
CX = length of setup string
DS:SI = far pointer to printer setup string

on return:
AX = error code if CF set, (invalid function)

INT 21,5E AL=03 Get Printer Setup (DOS 3.1+)

AH = 5E
AL = 03 get printer setup
BX = redirection list index (see ~INT 21,5F~ AL=2)
ES:DI = far pointer to buffer to receive setup string

on return:
AX = error code if CF set

INT 21,5E AL=04 Set Printer Mode (DOS 3.1+)

AH = 5E
AL = 04 set printer setup
BX = redirection list index (see INT 21,5F AL=2)
DX = printer mode to set (bit zero is set for binary mode and
clear for translated/text mode)

on return:
AX = error code if CF set

INT 21,5E AL=05 Get Printer Mode (DOS 3.1+)

AH = 5E
178

AL = 05 set printer setup


BX = redirection list index (see INT 21,5F AL=2)

on return:
AX = error code if CF set
DX = printer mode where bit zero is set for binary mode and
clear for translated mode

INT 21,5F AL=00 Get Redirection Mode (DOS 3.1+)

AH = 5F
AL = 00
BL = redirection type
= 03 printer
= 04 disk drive

on return:
AX = error code if CF is set
BH = device redirection state
= 00 redirection off
= 01 redirection on

- determines if disk or printer redirection is enabled


- fails if file sharing is not loaded

INT 21,5F AL=01 Set Redirection Mode (DOS 3.1+)

AH = 5F
AL = 01
BH = device redirection state
= 00 turn redirection off
= 01 turn redirection on
BL = redirection type
= 03 printer
= 04 disk drive

on return:
AX = error code if CF is set

- enables or disables disk or printer redirection


- local devices are used when redirection is off
179

- fails if file sharing is not loaded

INT 21,5F AL=02 Get Redirection List Entry (DOS 3.1+)

AH = 5F
AL = 02
BX = redirection list index
DS:SI = far pointer to a 16 byte buffer to hold device name
ES:DI = far pointer to a 128 byte buffer to hold network name

on return:
AX = error code if CF is set
= 1 invalid function code
= 12 no more files
BH = device status flag,
bit 0 = 0 device valid
bit 0 = 1 device invalid
BL = device type
= 3 printer
= 4 drive
CX = stored parameter value
DS:SI = far pointer to ASCIIZ local device name
ES:DI = far pointer to ASCIIZ network name

- value returned in CX is the value previously passed to


INT 21,5F with subfunction 3 in register CX
- registers DX and BP are destroyed
- fails if file sharing is not loaded

INT 21,5F AL=03 Redirect Device (DOS 3.1+)

AH = 5F
AL = 03
BL = device type
= 3 if printer
= 4 if drive
CX = parameter to save for caller
DS:SI = far pointer to ASCIIZ local device name
ES:DI = far pointer to ASCIIZ network name followed
by ASCIIZ password
180

on return
AX = error code if CF is set
= 1 invalid function code or
invalid source or destination string format or
source device already redirected
= 3 path not found
= 5 access denied
= 8 insufficient memory

- parameter passed in CX can later be retrieved by calls


to INT 21,5F subfunction 2
- local device name in DS:SI can be a drive designator
(D:), a printer name (PRN or LPTx), or a null string
- when a null string is followed by a password is used, DOS
tries granting access to the network directory using the
given password
- fails if file sharing is not loaded

INT 21,5F AL=04 Cancel Device Redirection (DOS 3.1+)

AH = 5F
AL = 04
DS:SI = far pointer to ASCIIZ local device name

on return
AX = error code if CF set
= 01 function code invalid
ASCIIZ string is not an existing source device
= 0F redirection paused on server

- local device name in DS:SI can be a drive designator


(D:), a printer name (PRN or LPTx), or a string beginning
with 2 backslashes "\\"
- when two backslashes are used for the string the connection
between the local machine and network directory terminates
- fails if file sharing is not loaded

INT 21,62 - Get PSP address (DOS 3.x)

AH = 62h
181

on return:
BX = segment address of current process

- this is useful for TSR's to access their own file handles

INT 22 - Program Terminate

no input data

- not an interrupt, but a vector to the terminate address


- copied to ~PSP~ offset 0Ah during program load
- do not execute this interrupt directly

INT 33 - Mouse Function Calls

~INT 33,0~ Mouse Reset/Get Mouse Installed Flag


~INT 33,1~ Show Mouse Cursor
~INT 33,2~ Hide Mouse Cursor
~INT 33,3~ Get Mouse Position and Button Status
~INT 33,4~ Set Mouse Cursor Position
~INT 33,5~ Get Mouse Button Press Information
~INT 33,6~ Get Mouse Button Release Information
~INT 33,7~ Set Mouse Horizontal Min/Max Position
~INT 33,8~ Set Mouse Vertical Min/Max Position
~INT 33,9~ Set Mouse Graphics Cursor
~INT 33,A~ Set Mouse Text Cursor
~INT 33,B~ Read Mouse Motion Counters
~INT 33,C~ Set Mouse User Defined Subroutine and Input Mask
~INT 33,D~ Mouse Light Pen Emulation On
~INT 33,E~ Mouse Light Pen Emulation Off
~INT 33,F~ Set Mouse Mickey Pixel Ratio
~INT 33,10~ Mouse Conditional OFF
~INT 33,13~ Set Mouse Double Speed Threshold
~INT 33,14~ Swap interrupt subroutines
~INT 33,15~ Get mouse driver state and memory requirements
~INT 33,16~ Save mouse driver state
~INT 33,17~ Restore mouse driver state
182

~INT 33,18~ Set alternate subroutine call mask and address


~INT 33,19~ Get user alternate interrupt address
~INT 33,1A~ Set mouse sensitivity
~INT 33,1B~ Get mouse sensitivity
~INT 33,1C~ Set mouse interrupt rate (InPort only)
~INT 33,1D~ Set mouse CRT page
~INT 33,1E~ Get mouse CRT page
~INT 33,1F~ Disable mouse driver
~INT 33,20~ Enable mouse driver
~INT 33,21~ Reset mouse software
~INT 33,22~ Set language for messages
~INT 33,23~ Get language number
~INT 33,24~ Get driver version, mouse type & ~IRQ~ number

- function is specified in AX
- a mickey is 1/200 inches

INT 33,0 - Mouse Reset/Get Mouse Installed Flag

AX = 00

on return:
AX = 0000 mouse driver not installed
FFFF mouse driver installed
BX = number of buttons

- resets mouse to default driver values:

. mouse is positioned to screen center


. mouse cursor is reset and hidden
. no interrupts are enabled (mask = 0)
. double speed threshold set to 64 mickeys per second
. horizontal mickey to pixel ratio (8 to 8)
. vertical mickey to pixel ratio (16 to 8)
. max width and height are set to maximum for video mode

INT 33,1 - Show Mouse Cursor

AX = 01

returns nothing
183

- increments the cursor flag; the cursor is displayed if flag


is zero; default flag value is -1

INT 33,2 - Hide Mouse Cursor

AX = 02

returns nothing

- decrements cursor flag; hides cursor if flag is not zero

INT 33,3 - Get Mouse Position and Button Status

AX = 03

on return:
CX = horizontal (X) position (0..639)
DX = vertical (Y) position (0..199)
BX = button status

- values returned in CX, DX are the same regardless of


video mode

INT 33,4 - Set Mouse Cursor Position

AX = 4
CX = horizontal position
DX = vertical position

returns nothing

- default cursor position is at the screen center


- the position must be within the range of the current video
mode
- the position may be rounded to fit screen mode resolution
184

INT 33,5 - Get Mouse Button Press Information

AX = 5
BX = 0 left button
1 right button

on return:
BX = count of button presses (0-32767), set to zero after call
CX = horizontal position at last press
DX = vertical position at last press
AX = status

INT 33,6 - Get Mouse Button Release Information

AX = 6
BX = 0 left button
1 right button

on return:
BX = count of button releases (0-32767), set to zero after call
CX = horizontal position at last release
DX = vertical position at last release
AX = status

INT 33,7 - Set Mouse Horizontal Min/Max Position

AX = 7
CX = minimum horizontal position
DX = maximum horizontal position

returns nothing

- restricts mouse horizontal movement to window


- if min value is greater than max value they are swapped

INT 33,8 - Set Mouse Vertical Min/Max Position

AX = 8
CX = minimum vertical position
DX = maximum vertical position
185

returns nothing

- restricts mouse vertical movement to window


- if min value is greater than max value they are swapped

INT 33,9 - Set Mouse Graphics Cursor

AX = 9
BX = horizontal hot spot (-16 to 16)
CX = vertical hot spot (-16 to 16)
ES:DX = pointer to screen and cursor masks (16 byte bitmap)

returns nothing

- screen mask is AND'ed to screen Cursor Mask is XOR'ed


- bytes 0-7 form the screen mask bitmap
- bytes 8-F form the cursor mask bitmap

INT 33,A - Set Mouse Text Cursor

AX = 0A
BX = 00 software cursor
01 hardware cursor
CX = start of screen mask or hardware cursor scan line
DX = end of screen mask or hardware cursor scan line

returns nothing

INT 33,B - Read Mouse Motion Counters

AX = 0B

on return:
CX = horizontal mickey count (-32768 to 32767)
DX = vertical mickey count (-32768 to 32767)

- count values are 1/200 inch intervals (1/200 in. = 1 mickey)

INT 33,C - Set Mouse User Defined Subroutine and Input Mask

AX = 0C
186

ES:DX = far pointer to user interrupt


CX = user interrupt mask:

bit0: cursor position changed


bit1: left button pressed
bit2: left button released
bit3: right button pressed
bit4: right button released
Τα υπόλοιπα bits του CX δεν χρησιμοποιούνται.

returns nothing

- routine at ES:DX is called if an event occurs and the


corresponding bit specified in user mask is set
- routine at ES:DX receives parameters in the following
registers:

AX = condition mask causing call


CX = horizontal cursor position
DX = vertical cursor position
DI = horizontal counts
SI = vertical counts
DS = mouse driver data segment
BX = button state:

bit0: left button (1 = pressed)


bit1: right button (1 = pressed)
Τα υπόλοιπα bits του ΒΧ είναι αχρησιμοποίητα.

- initial call mask and user routine should be restore on exit


from user program
- user program may need to set DS to it's own segment

INT 33,F - Set Mouse Mickey Pixel Ratio

AX = 0F
CX = horizontal ratio (1..32767, default 8)
DX = vertical ratio (1..32767, default 16)

returns nothing
187

- sets the ratio between physical cursor movement (mickeys) and


screen coordinate changes
- CX and DX must be unsigned (high bit must be 0)

INT 33,13 - Set Mouse Double Speed Threshold

AX = 13h
DX = threshold speed (mickeys per second, default 64)

returns nothing

- cursor speed is doubled when the cursor moves across the


screen at the threshold speed

INT 33,15 - Get Mouse Driver State and Memory Requirements

AX = 15h

on return
BX = buffer size need to hold current mouse state

- used before mouse functions 16h and 17h to determine memory


needed to save mouse state before giving up control of mouse
to another program

INT 33,16 - Save Mouse Driver State

AX = 16h
ES:DX = far pointer to mouse state save buffer

returns nothing

- used to save mouse information before relinquishing control


to another programs mouse handler

INT 33,17 - Restore Mouse Driver State

AX = 17h
ES:DX = far pointer to mouse state save buffer

returns nothing
188

- used to restore mouse information after regaining control


from another programs mouse handler

INT 33,1A - Set Mouse Sensitivity

AX = 1A
BX = horizontal coordinates per pixel (σ 100)
CX = vertical coordinates per pixel (σ 100)
DX = double speed threshold

returns nothing

- sets mouse sensitivity by setting the ratio of the mouse


coordinates per screen pixel
- provides same results as calls to both ~INT 33,F~ and ~INT
33,13~
- these values are not reset by ~INT 33,0~

INT 33,1B - Get Mouse Sensitivity

AX = 1B

on return:
BX = horizontal coordinates per pixel (σ 100)
CX = vertical coordinates per pixel (σ 100)
DX = double speed threshold

- returns mouse sensitivity information as the number of mouse


coordinates per screen pixel

INT 33,1F - Disable Mouse Driver

AX = 1F

on return:
AX = 001F if successful
FFFF if error
ES:BX = previous ~INT 33~ vector
189

- restores vectors for ~INT 10~ and INT 71 (8088/86) or INT 74


(286+)
- ~INT 33~ interrupt vector (software) is not affected
- use of the vector returned in ES:BX to restore the previous
INT 33 vector can cause problems since it contains the value of INT
33 before the driver was installed; any other hooks into INT 33 set
after driver installation will not receive service

INT 33,20 - Enable Mouse Driver

AX = 20h

returns nothing
- reinstalls the mouse drivers interrupt vectors for INT 10 and
INT 71 (8088/86) and INT 74 (286/386)

ΙNT 33,21 - Reset Mouse Software

AX = 21h

on return:
AX = 0021 mouse driver not installed
FFFF mouse driver installed
BX = 2 mouse driver installed

- similar to ~INT 33,0~ but does not reset the mouse hardware
or
display variables
- both AX and BX must be correct for successful reset
- interrupt routines set through ~INT 33,18~ are preserved
- resets the mouse to the following defaults:

. mouse is positioned to screen center


. mouse cursor is reset and hidden
. no interrupts are enabled (mask = 0)
. double speed threshold set to 64 mickeys per second
. horizontal mickey to pixel ratio (8 to 8)
. vertical mickey to pixel ratio (16 to 8)
. max width and height are set to maximum for video mode
190

INT 33,24 - Get Driver Version, Mouse Type & IRQ Number

AX = 24h

on return:
BH = major version (see below)
BL = minor version (see below)
CH = mouse type:
= 1 bus mouse
= 2 serial mouse
= 3 InPort mouse
= 4 PS/2 mouse
= 5 Hewlett Packard mouse
CL = IRQ number:
= 0 PS/2
= 2 ~IRQ~ 2
= 5 IRQ 5
= 7 IRQ 7

- version 6.1 would be represented as BH = 06h, BL = 10h

You might also like