Προγραμματισμός σε επίπεδο μηχανής

Διομήδης Σπινέλλης
Τμήμα Διοικητικής Επιστήμης και Τεχνολογίας
Οικονομικό Πανεπιστήμιο Αθηνών
dds@aueb.gr

Οικογένειες επεξεργαστών

Οικογένειες επεξεργαστών

Η αρχιτεκτονική εντολών ενός επεξεργαστή σχεδιάζεται γύρω από τους παρακάτω άξονες:

Η οικογένεια επεξεργαστών iAPX86

Φωτογραφίες

Οι παρακάτω φωτογραφίες προέρχονται από το δικτυακό τόπο της Intel (http://www.intel.com/intel/intelis/museum/exhibit/hist_micro/hof/hof_main.htm>). Προσοχή, δεν είναι στην ίδια κλίμακα!


8080


8086/8088


80286


80486


Pentium


Pentium II


Pentium III


Pentium 4

Καταχωρητές

Προσδιορισμός τελεστέων

Συνδιασμοί τελεστών:

Ενδείκτης διακλάδωσης

CF:
(Carry flag)
Κρατούμενο (Carry):
1 αν η πράξη δημιούργησε κρατούμενο.
ZF:
(Zero flag)
Μηδέν:
1 αν το αποτέλεσμα της πράξης είναι 0.
SF:
(Sign flag)
Πρόσημο (sign)
1 αν το αποτέλεσμα είναι αρνητικός αριθμός.
PF:
(Parity flag)
Ισοτιμία
1 αν το αποτέλεσμα έχει μονό αριθμό από bit που είναι 1.
OF:
(Overflow flag)
Υπερχείλιση:
1 αν το αποτέλεσμα δε μπορεί να παρασταθεί ως θετικός η αρνητικός αριθμός.

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

MOV προορισμός, πηγή
(Move)
Μεταφορά
προορισμός <- πηγή
PUSH πηγή
Μεταφορά στη στοίβα
SP <- SP - 2
[SP] <- πηγή
POP προορισμός
Μεταφορά από τη στοίβα
προορισμός <- [SP]
SP <- SP + 2
XCHG προορισμός, πηγή
(Exchange)
Εναλλαγή
προορισμός <- πηγή
πηγή <- προορισμός
(ταυτόχρονα)

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

ADD προορισμός, πηγή
(Add)
Πρόσθεση
προορισμός <- προορισμός + πηγή
INC προορισμός
(Increment)
Αύξηση κατά ένα
προορισμός <- προορισμός + 1
SUB προορισμός, πηγή
(Subtract)
Αφαίρεση
προορισμός <- προορισμός - πηγή
DEC προορισμός
(Decrement)
Μείωση κατά ένα
προορισμός <- προορισμός - 1
NEG προορισμός
(Negate)
Αλλαγή προσήμου
προορισμός <- - προορισμός
CMP προορισμός, πηγή
(Compare)
Σύγκριση
Εκτελείται η πράξη προορισμός - πηγή και ενημερώνονται οι ενδείκτες διακλάδωσης.
MUL πηγή
(Multiply)
Πολλαπλασιασμός
DX:AX <- AX * πηγή
DIV πηγή
(Divide)
Διαίρεση
AX <- AX / πηγή
DX <- AX mod πηγή

Εντολές δυαδικών ψηφίων

AND προορισμός, πηγή
Σύζευξη
προορισμός <- προορισμός & πηγή
OR προορισμός, πηγή
Διάζευξη
προορισμός <- προορισμός | πηγή
XOR προορισμός, πηγή
Αποκλειστική διάζευξη
προορισμός <- προορισμός ^ πηγή
NOT προορισμός
Αντιστροφή
προορισμός <- ~ προορισμός
TEST προορισμός, πηγή
Έλεγχος
SHL προορισμός, αριθμός
(Shift left)
Ολίσθηση (Shift) αριστερά
προορισμός <- προορισμός << πηγή
SHR προορισμός, αριθμός
(Shift right)
Ολίσθηση δεξιά
προορισμός <- προορισμός >> πηγή
SAR προορισμός, αριθμός
(Shift arithmetic right)
Αριθμητική ολίσθηση δεξιά
προορισμός <- προορισμός >> πηγή
ROL προορισμός, αριθμός
(Rotate left)
Περιστροφή αριστερά
ROR προορισμός, αριθμός
(Rotate right)
Περιστροφή δεξιά

Εντολές άλματος

JMP προορισμός
'Αλμα
CALL προορισμός
Κλήση
RET
(Return)
Επιστροφή
JA/JNBE προορισμός
(Jump above)
'Αλμα αν μεγαλύτερο (χωρίς πρόσημο)
JAE/JNB προορισμός
(Jump above or equal)
'Αλμα αν μεγαλύτερο ή ίσο (χωρίς πρόσημο)
JB/JNAE προορισμός
(Jump bellow)
'Αλμα αν μικρότερο (χωρίς πρόσημο)
JBE/JNA προορισμός
(Jump below or equal)
'Αλμα αν μικρότερο ή ίσο (χωρίς πρόσημο)
JC προορισμός
(Jump carry)
'Αλμα αν κρατούμενο
JNC προορισμός
(Jump no carry)
'Αλμα αν όχι κρατούμενο
JE/JZ προορισμός
(Jump equal)
'Αλμα αν ίσο
JNE/JNZ προορισμός
(Jump not equal)
'Αλμα αν όχι ίσο
JG/JNLE προορισμός
(Jump greater)
'Αλμα αν μεγαλύτερο (με πρόσημο)
JGE/JNL προορισμός
(Jump greater or equal)
'Αλμα αν μεγαλύτερο ή ίσο (με πρόσημο)
JL/JNGE προορισμός
(Jump less)
'Αλμα αν μικρότερο (με πρόσημο)
JLE/JNG προορισμός
(Jump less or equal)
'Αλμα αν μικρότερο ή ίσο (με πρόσημο)
JO προορισμός
(Jump overflow)
'Αλμα αν υπερχείλιση
JNO προορισμός
(Jump no overflow)
'Αλμα αν όχι υπερχείλιση
JS προορισμός
(Jump sign)
'Αλμα αν πρόσημο
JNS προορισμός
(Jump no sign)
'Αλμα αν όχι πρόσημο

Παράσταση εντολών

Κωδικοποίηση εντολών σε επεξεργαστές της Intel


Βασική κωδικοποίηση εντολών


Κωδικοποίηση εντολών ενός byte


Το byte ModR/M προσδιορίζει τις διευθύνσεις των εντολών


Το byte SIB (scale, index, base) επιτρέπει τον ορθόγωνο προσδιορισμό κλίμακας, δείκτη και βάσης.

Βιβλιογραφία

Ασκήσεις

Εργαστηριακές ασκήσεις

1. Αθροίζοντας αριθμούς

  1. Ανοίξτε παράθυρο εντολών (run - command) ή φορτώστε το λειτουργικό σύστημα MS-DOS
  2. Δώστε την εντολή debug
    C:>debug
    
  3. Δώστε την εντολή Α (assemble)
    -a
    
  4. Γράψτε τις συμβολικές εντολές (mov ax, 0) κλπ. Οι διευθύνσεις μνήμης εμφανίζονται μόνες τους. Τα σχόλια που ακολουθούν το ; δε χρειάζεται να γραφούν.
    0C20:0100 mov ax,0		; Βάλε (move) στον καταχωρητή ΑΧ την τιμή 0
    0C20:0103 mov bx,0		; Βάλε (move) στον καταχωρητή ΒΧ την τιμή 0 
    0C20:0106 add bx, ax		; Πρόσθεσε στον ΒΧ τον ΑΧ
    0C20:0108 inc ax		; Αύξησε (increment) τον ΑΧ κατά 1
    0C20:0109 cmp ax, a		; Σύγκρινε (compare) τον ΑΧ με το 10
    0C20:010C jbe 106		; 'Αλμα αν το αποτέλεσμα είναι μικρότερο ή ίσο (jump below or equal) στη διεύθυνση 106
    0C20:010E int 3			; Διακοπή της λειτουργίας
    0C20:010F			; Πατήστε ENTER εδώ
    
  5. Δείτε την κωδικοποίηση των εντολών με την εντολή U (unassemble):
    -u100
    Διεύθυνση Κωδικοποίηση  Συμβολική εντολή
    0C20:0100 B80000        MOV     AX,0000
    0C20:0103 BB0000        MOV     BX,0000
    0C20:0106 01C3          ADD     BX,AX
    0C20:0108 40            INC     AX
    0C20:0109 3D0A00        CMP     AX,000A
    0C20:010C 76F8          JBE     0106
    0C20:010E CC            INT     3
    
  6. Εκτελέστε το πρόγραμμά σας και εξετάστε το αποτέλεσμα στον καταχωρητή ΒΧ. Είναι αυτό που περιμένατε;
    -g=100
    
    AX=000B  BX=0037  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
    DS=0C20  ES=0C20  SS=0C20  CS=0C20  IP=010E   NV UP EI PL NZ NA PO NC
    0C20:010E CC            INT     3
    
  7. Εκτελέστε το πρόγραμμά σας βήμα βήμα με την εντολή T (trace):
    -t=100
    AX=0000  BX=0000  CX=0000  DX=0080  SP=FFEE  BP=0000  SI=0000  DI=0000
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    Καταχωρητές
    
    DS=0C1C  ES=0C1C  SS=0C1C  CS=0C1C  IP=0103   NV UP EI PL ZR NA PE NC
                                        ^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^
    				    |         Ενδείκτες διακλάδωσης
    				    Μετρητής προγράμματος
    
    0C1C:0103 BB0000        MOV     BX,0000
         ^^^^               ^^^^^^^^^^^^^^^
         Διεύθυνση μνήμης   Επόμενη εντολή που θα εκτελεστεί
    -t
    
    AX=0000  BX=0000  CX=0000  DX=0080  SP=FFEE  BP=0000  SI=0000  DI=0000
    DS=0C1C  ES=0C1C  SS=0C1C  CS=0C1C  IP=0106   NV UP EI PL ZR NA PE NC
    0C1C:0106 01D8          ADD     AX,BX
    -t
    
    AX=0000  BX=0000  CX=0000  DX=0080  SP=FFEE  BP=0000  SI=0000  DI=0000
    DS=0C1C  ES=0C1C  SS=0C1C  CS=0C1C  IP=0108   NV UP EI PL ZR NA PE NC
    0C1C:0108 40            INC     AX
    -t
    
    AX=0001  BX=0000  CX=0000  DX=0080  SP=FFEE  BP=0000  SI=0000  DI=0000
    DS=0C1C  ES=0C1C  SS=0C1C  CS=0C1C  IP=0109   NV UP EI PL NZ NA PO NC
    0C1C:0109 3D0A00        CMP     AX,000A
    -t
    
    AX=0001  BX=0000  CX=0000  DX=0080  SP=FFEE  BP=0000  SI=0000  DI=0000
    DS=0C1C  ES=0C1C  SS=0C1C  CS=0C1C  IP=010C   NV UP EI NG NZ AC PO CY
    0C1C:010C 76F8          JBE     0106
    -t
    
    AX=0001  BX=0000  CX=0000  DX=0080  SP=FFEE  BP=0000  SI=0000  DI=0000
    DS=0C1C  ES=0C1C  SS=0C1C  CS=0C1C  IP=0106   NV UP EI NG NZ AC PO CY
    0C1C:0106 01D8          ADD     AX,BX
    
    ...
    
  8. Αυξήστε το όριο της άθροισης από 10 σε 100:
    -a109
    0C20:0109 cmp ax, 64		; Σύγκρινε τον καταχωρητή ΑΧ με το 100
    0C20:010C			; Πατήστε ENTER εδώ
    -g=100
    
  9. Εκτελέστε το πρόγραμμά σας και εξετάστε το αποτέλεσμα στον καταχωρητή ΒΧ. Είναι αυτό που περιμένατε;
    AX=0065  BX=13BA  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
    DS=0C20  ES=0C20  SS=0C20  CS=0C20  IP=010E   NV UP EI PL NZ NA PO NC
    0C20:010E CC            INT     3
    
  10. Βγήτε από το πρόγραμμα debug
    -q
    C:>
    

2. Εμφάνιση των χαρακτήρων του πίνακα ASCII

  1. Γράψτε το πρόγραμμα:
    C:\>debug
    -a
    0C1C:0100 mov dl,20		; Πρώτος χαρακτήρας ASCII (το κενό)
    0C1C:0102 mov ah,2		; Εντολή για εμφάνιση του χαρακτήρα στην οθόνη
    0C1C:0104 int 21		; Εκτέλεση της εντολής του DOS
    0C1C:0106 add dl,1		; Αύξησε το χαρακτήρα κατά 1
    0C1C:0109 cmp dl,80		; Είναι ο τελευταίος; (128)
    0C1C:010C jne 102		; Αν όχι πήγαινε στη διεύθυνση 102 (jump not equal)
    0C1C:010E int 3			; Διακοπή του προγράμματος
    0C1C:010F			; Πατήστε ENTER εδώ
    
  2. Δείτε την κωδικοποίηση των εντολών με την εντολή U (unassemble):
    -u100
    0C1C:0100 B220          MOV     DL,20
    0C1C:0102 B402          MOV     AH,02
    0C1C:0104 CD21          INT     21
    0C1C:0106 80C201        ADD     DL,01
    0C1C:0109 80FA80        CMP     DL,80
    0C1C:010C 75F4          JNZ     0102
    0C1C:010E CC            INT     3
    
  3. Εκτελέστε το πρόγραμμά σας και δείτε το αποτέλεσμα στην οθόνη σας.
    -g=100
     !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmno
    pqrstuvwxyz{|}~¦
    AX=027F  BX=0000  CX=0000  DX=0080  SP=FFEE  BP=0000  SI=0000  DI=0000
    DS=0C1C  ES=0C1C  SS=0C1C  CS=0C1C  IP=010E   NV UP EI PL ZR NA PE NC
    0C1C:010E CC            INT     3
    

3. Συνεχίζοντας

Δοκιμάστε να γράψετε και να εκτελέσετε και άλλα μικρά προγράμματα ή παραλλαγές αυτών που γράψατε.

Παράδειγμα κύκλου εντολών

Το πρόγραμμα

Διεύθυνση Κωδικός εντολής   Συμβολική παράσταση εντολής
     0100 B80100            MOV     AX,0001
     0103 050400            ADD     AX,0004
     0106 A31000            MOV     [0010],AX
     0109 3D0500            CMP     AX,0000
     010C 74F2              JZ      0100

Ο κύκλος των εντολών (επανάληψη)

  1. Ανάκληση εντολής (Instruction fetch)
  2. Αποκωδικοποίηση εντολής (Instruction decode)
  3. Εκτέλεση εντολής (Instruction execution)
  4. Πρόσβαση μνήμης (Memory access)
  5. Εγγραφή
Ο τρόπος που θα εκτελεστούν οι παραπάνω εντολές από την ΚΜΕ σύμφωνα με το κύκλο των εντολών είναι ο εξής:

0100 B80100 MOV AX,0001

ΜΠΚΔιΜΚΔεΜΚΕΑΧΑBΓ
Ανάκληση100100-B80100----
Αποκωδικοποίηση103100-B80100-0001--
Εκτέλεση103100-B80100-0001-0001
Εγγραφή103100-B8010000010001-0001

0103 050400 ADD AX,0004

ΜΠΚΔιΜΚΔεΜΚΕΑΧΑBΓ
Ανάκληση103103-0504000001---
Αποκωδικοποίηση106103-050400000100010004-
Εκτέλεση106103-0504000001000100040005
Εγγραφή106103-0504000005000100040005

0106 A31000 MOV [0010],AX

ΜΠΚΔιΜΚΔεΜΚΕΑΧΑBΓ
Ανάκληση106106-A310000005---
Αποκωδικοποίηση109106-A31000000500000010-
Εκτέλεση10900100005A310000005000000100010
Πρόσβαση μνήμης10900100005A310000005000000100010

0109 3D0500 CMP AX,0005

ΜΠΚΔιΜΚΔεΜΚΕΑΧΑBΓ
Ανάκληση109109-3D05000005---
Αποκωδικοποίηση10C109-3D0500000500050005-
Εκτέλεση10C109-3D05000005000500050000

010C 74F2 JZ 0100

ΜΠΚΔιΜΚΔεΜΚΕΑΧΑBΓ
Ανάκληση10C10C-74F20005---
Αποκωδικοποίηση10E10C-74F20005010EFFF2-
Εκτέλεση10E10C000574F20005010EFFF20100
Πρόσβαση μνήμης10010C000574F20005010EFFF20010