ΗΥ-340 Γλώσσες και Μεταφραστές Φροντιστήριο Παραγωγή τελικού κώδικα Από τον ενδιάμεσο κώδικα στον τελικό (1/2) Τα ορίσματα των εντολών ενδιάμεσου κώδικα είναι του τύπου expr*. Αυτές οι εκφράσεις θα πρέπει να μετατραπούν στα κατάλληλα ορίσματα για τις εντολές τελικού κώδικα. Αυτό σημαίνει ότι θα πρέπει να υπάρχει κάποι «μηχανισμός» όπου με βάση κάποιο expr* να κατασκευάζει κατάλληλα ένα vmarg*. 2 Από τον ενδιάμεσο κώδικα στον τελικό (2/2) Παραγωγή τελικού κώδικα Η παραγωγή τελικού κώδικα γίνεται μέσω της συνάρτησης emit όπως και στον ενδιάμεσο κώδικα (με την διαφορά ότι έχει ένα όρισμα τύπου instruction*) 3 4
Incomplete jumps (1/2) Τα target labels των jump εντολών του ενδιάμεσου κώδικα θα πρέπει να τροποποιηθούν στις αντίστοιχες jump εντολές τελικού κώδικα. Ο λόγ είναι ότι δεν αντιστοιχεί μία εντολή ενδιάμεσου κώδικα σε μία εντολή τελικού κώδικα. Συνήθως, οι εντολές τελικού κώδικα είναι περισσότερες από τις εντολές ενδιάμεσου. Η λύση είναι να εισάγουμε το πεδίο taddress στις εντολές ενδιάμεσου κώδικα και αυτό να συμπληρώνεται κατά την παραγωγή τελικού κώδικα με τον αριθμό της πρώτης εντολής τελικού κώδικα που αντιστοιχεί σε αυτή. Incomplete jumps (2/2) patch_incomplete_jumps() { for each incomplete jump x do { if x.iaddress = intermediate code size then instructions[x.instrno].result = target code size; else instructions[x.instrno].result ti [ i t ] = quads[x.iaddress].taddress; [ dd ] dd } } 5 6 Τελικός κώδικας για Λογικές Εκφράσεις (1/2) Τελικός κώδικας για Λογικές Εκφράσεις (2/2) ενδιάμεσ κώδικας NOT arg1 result taddress jeq arg1 false _ assign false result jump +2 assign true result _ +3 ενδιάμεσ κώδικας AND arg1 arg2 result taddress jeq arg1 false _ jeq arg2 false assign true result jump _ +4 +3 ενδιάμεσ κώδικας ΛΟΓΙΚΕΣ ΕΚΦΡΑΣΕΙΣ +2 assign false result OR arg1 arg2 result taddress jeq arg1 true _ +4 jeq arg2 true +3 assign false result ΛΟΓΙΚΕΣ ΕΚΦΡΑΣΕΙΣ +2 jump assign true result _ 7 8
Τελικός κώδικας για Συναρτήσεις (1/2) Τελικός κώδικας για Συναρτήσεις (2/2) ενδιάμεσ κώδικας FUNCSTART result taddress enterfunc RETURN result taddress assign retval result jump _ FUNCEND result taddress exitfunc ΚΩΔΙΚΑΣ ΣΥΝΑΡΤΗΣΕΩΝ Επειδή όμως υποστηρίζεται ο ορισμός συνάρτησης μέσα σε μία άλλη χρησιμοποιείται μία λίστα (funcstack): Στο funcstart γίνεται push η συνάρτηση στην στοίβα Στο funcend γίνεται pop και γίνονται patch τα target labels των εντολών jump που βρίσκονται στην returnlist. Στο return εισάγουμε τον αριθμό εντολής τελικού κώδικα του jump στην returnlist της συνάρτησης που βρίσκεται στην κορυφή της στοίβας. Επειδή το target label του jump δεν είναι γνωστό πριν παραχθεί κώδικας για το funcend, διατηρείται μία λίστα (returnlist) για κάθε τέτοιο jump και θα συμπληρώνονται τα target labels αυτών των jump αφού παραχθεί κώδικας για το funcend. 9 10 Τεχνική παραγωγής ενδιάμεσου κώδικα ΗΥ-340 Γλώσσες και Μεταφραστές Φροντιστήριο Virtual Machine 11
Τελικός κώδικας για το calculator (1/2) Τελικός κώδικας για το calculator (2/2) Μπορούμε να παράγουμε από την εφαρμογή calculator τελικό κώδικα μετατρέποντας τον ενδιάμεσο κώδικα (quads) σε τελικό σε αυτήν την περίπτωση η μετατροπή είναι τετριμμένη ρμμ οι εντολές τελικού κώδικα έχουν ακριβώς την ίδια σημασιολογία με τις εντολές ενδιάμεσου κώδικα η αντιστοίχηση των εντολών ενδιάμεσου με τελικού κώδικα είναι μία πρ μία Binary αρχείο που μπορεί να εκτελεστεί από την εικονική μηχανή 13 14 Σχεδίαση ενός binary αρχείου (1/2) Σχεδίαση ενός binary αρχείου (2/2) μαγικός αριθμός (κατά προτίμηση μοναδικός) αριθμός μεταβλητών που περιέχει το πρόγραμμα αριθμός εντολών (τελικού κώδικα) που περιέχει το πρόγραμμα εντολές το format μιας εντολής opcode (1 byte) result (5 bytes) arg1 (5 bytes) arg2 (5 bytes) το format ενός argument είναι το εξής argument type (1 byte) σταθερά ή μεταβλητή value (4 bytes) offset στον πίνακα των μεταβλητών του προγράμματ αν ο τύπ είναι μεταβλητή η πραγματική τιμή αν ο τύπ είναι σταθερά 15 16
Εικονική Μηχανή η μοναδική λειτουργία της εικονικής μηχανής είναι να εκτελεί ένα αρχείο τελικού κώδικα φορτώνει το αρχείο στην μνήμη αριθμός μεταβλητών αντιστοιχίζει τις μεταβλητές σε θέσεις μνήμης αρχίζει να εκτελεί τις εντολές σειριακά η μηχανή του calculator δεν έχει συνθήκες, βρόχους ή συναρτήσεις Φόρτωμα binary αρχείου (1/2) Ανάγνωση χαρακτηριστικών Δέσμευση μνήμης για τις εντολές Φόρτωμα των εντολών 17 18 Φόρτωμα binary αρχείου (2/2) Προδιαγραφές Εικονικής Μηχανής (1/2) Τα δεδομένα που αποθηκεύονται στη μνήμη της εικονικής μηχανής για οποιουδήποτε τύπου VMArg Μνήμη της εικονικής μηχανής η οποία χρησιμοποιείται για την αποθήκευση των μεταβλητών του προγράμματ που εκτελείται λί Βοηθητικοί καταχωρητές Program Counter, πλήθ εντολών προγράμματ και μνήμη εντολών 19 20
Προδιαγραφές Εικονικής Μηχανής (2/2) Εκτέλεση Προγράμματ (1/5) Μόλις φορτωθεί το πρόγραμμα στην εικονική μηχανή αυτή αρχίζει να εκτελεί τον σειριακά τις εντολές Εκτέλεση της κατάλληλης συνάρτησης 21 22 Εκτέλεση Προγράμματ (2/5) Επειδή το πακετάρισμα των εντολών είναι πανομοιότυπο για εντολές που παίρνουν 1, 2 ή 3 παραμέτρους... Εκτέλεση Προγράμματ (3/5) Μετά τις κλήσεις της συνάρτησης translate_operand, έχουμε στη διάθεσή μας pointers στις τιμές των παραμέτρων της εκάστοτε εντολής 23 24
Εκτέλεση Προγράμματ (4/5) Εκτέλεση Προγράμματ (5/5) simple.clc Binary (simple.exe) Έτσι,, οποιουδήποτε τύπου κι αν είναι η παράμετρ VMArg, είμαστε σίγουροι σε αυτό το σημείο ότι ο pointer VMMemCell, δείχνει πάντα στη σωστή τιμή της παραμέτρου, είτε αυτή είναι σταθερά είτε μεταβλητή Calc VM 25 26