Ilias95 Δημοσ. 1 Σεπτεμβρίου 2017 Δημοσ. 1 Σεπτεμβρίου 2017 Γεια χαρά,Γράφω έναν symbolic assembler σε C για μια απλή assembly. Για να χειριστώ τα σύμβολα που περιέχονται στον κώδικα πρέπει να κάνω δύο περάσματα το αρχείο, οπότε βλέπω δύο περιπτώσεις:Α Περίπτωση: Κατά τη διάρκεια του πρώτου περάσματος, αφού κάνω strip κάθε γραμμή από whitespace και comments την αποθηκεύω σε έναν buffer στη μνήμη πχ. char **lines. Γι' αυτόν τον buffer δεσμεύω μνήμη δυναμικά. Λίγη στην αρχή και περισσότερη σιγά σιγά όσο χρειάζεται αναλόγως πόσο μεγάλο είναι το αρχείο. Στο τέλος έχω κρατήσει στον buffer όλες τις γραμμές του αρχείου (μετά το stripping) και μπορώ να κλείσω το αρχείο μου. Στο δεύτερο πέρασμα απλά διαβάζω τα περιεχόμενα του buffer.Β Περίπτωση: Διαβάζω το αρχείο γραμμή-γραμμή, κάνω strip το whitespace και τα σχόλια και χτίζω το symbol table. Αφού τελειώσω ξανα-διαβάζω το αρχείο πάλι από την αρχή, κάνω ξανά strip whitespace & comments + έξτρα parsing κάθε γραμμή για να γίνει το translation σε machine code.Στην Α περίπτωση θα χρειαστεί να δεσμεύσω παραπάνω πόρους, αλλά το πρόγραμμα θα είναι πιο γρήγορο. Ενδεικτικά σκέφτομαι ότι αν κάθε γραμμή είναι πάνω-κάτω 20 bytes και έχω σαν input ένα αρχείο με 100.000 instructions θα πρέπει να δεσμεύσω περίπου 2ΜΒ μνήμη το οποίο δεν μου φαίνεται και τίποτα. Η Β περίπτωση είναι πιο απλή στην υλοποίηση και χωρίς να δεσμεύσω έξτρα πόρους, αλλά φαντάζομαι θα καθυστερώ περισσότερο λόγω I/O μιας και θα διαβάσω όλο το αρχείο γραμμή-γραμμή δύο φορές.Οκ, ο assembler που γράφω είναι για την πλάκα μου και δεν έχει και τόση σημασία για εμένα, αλλά τι θα γινόταν σε ένα πραγματικό σενάριο; Τι θα ήταν προτιμότερο;Ευχαριστώ πολύ!
NickSym Δημοσ. 2 Σεπτεμβρίου 2017 Δημοσ. 2 Σεπτεμβρίου 2017 Η RAM αυξάνεται εύκολα αλλά η ταχύτητα ανάγνωσης από τον δίσκο όχι. Προτιμησε λοιπόν να το κρατάς στη μνήμη και αν θες να κάνεις βελτιστοποίηση χρησιμοποίησε κάποιο έξυπνο μοντέλο για την αποθήκευση του. Για τον σκοπό που το θες, είθισται να διαβάζεται το αρχείο μια φορά και η αποκωδικοποιηση του να γίνεται ενώσω διαβάζεται.
solarpower Δημοσ. 2 Σεπτεμβρίου 2017 Δημοσ. 2 Σεπτεμβρίου 2017 Δες αυτό αν δουλεύεις σε Windows και θες να έχεις διευθύνσεις συνεχόμενες πριν δώσεις μνήμη σε αυτές. Αυτό χρειάζεται αν κάνεις "σειριακό" πέρασμα και δεν θες να αλλάξει η βάση του μπλοκ μνήμης, η πρώτη διεύθυνση, (με αντιγραφή σε μεγαλύτερο) στη ζήτηση περισσότερης μνήμης. https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx Δες επίσης και αυτό http://www.catb.org/esr/structure-packing/ ώστε να μειώσεις το μέγεθος απαιτούμενης μνήμης.
Ilias95 Δημοσ. 2 Σεπτεμβρίου 2017 Μέλος Δημοσ. 2 Σεπτεμβρίου 2017 Ωραία, άρα θα το κρατήσω στη μνήμη. Δες αυτό αν δουλεύεις σε Windows και θες να έχεις διευθύνσεις συνεχόμενες πριν δώσεις μνήμη σε αυτές. Αυτό χρειάζεται αν κάνεις "σειριακό" πέρασμα και δεν θες να αλλάξει η βάση του μπλοκ μνήμης, η πρώτη διεύθυνση, (με αντιγραφή σε μεγαλύτερο) στη ζήτηση περισσότερης μνήμης. https://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx Δες επίσης και αυτό http://www.catb.org/esr/structure-packing/ ώστε να μειώσεις το μέγεθος απαιτούμενης μνήμης. Ναι, δεν το διευκρίνισα, σε Linux είμαι. Υπάρχει κάτι αντίστοιχο με το πρώτο link για Linux (ή ακόμα καλύτερα cross-platform);Επίσης πολύ ωραίο το 2ο link, αλλά νομίζω ότι δεν κάνει apply εδώ γιατί είχα στο μυαλό μου να κρατήσω το αρχείο σαν list of strings στη μνήμη. Από την άλλη σκέφτομαι τώρα αν είναι εύκολο να κάνω κατευθείαν parsing στο 1ο πέρασμα (εκτός από symbols extraction). Έτσι θα μπορούσα για κάθε γραμμή να έχω ένα struct instruction ανά διαφορετικό instruction και να κρατάω αυτό στη μνήμη το οποίο θα έπιανε και λιγότερο χώρο (με χρήση bit fields etc.).
solarpower Δημοσ. 2 Σεπτεμβρίου 2017 Δημοσ. 2 Σεπτεμβρίου 2017 Ο Assembler είναι σχετικά εύκολος να υλοποιηθεί, γιατί ξέρεις ότι κάθε γραμμή του μπορεί να είναι εντολή ή κάποια σταθερά, οπότε αυτό που θες είναι μια δομή που να κρατάει για κάθε γραμμή το πόσα bytes είναι, τι περιέχει, και το τυχόν όνομα που πρέπει να επιλυθεί, και για βοήθεια να έχεις και ένα πεδίο ακόμα που να λέει σε ποιο offset γράφεται (το υπολογίζεις καθώς κτίζεις τη δομή). Συνάμα πρέπει να γράφεις μια λίστα με όλα τα ονόματα και σε ποιο σημείο στη δομή βρίσκονται (ως θέση και όχι ως αναφορά). Έτσι στο δεύτερο πέρασμα περνάς από κάθε στοιχείο της δομής,όπου βρίσκεις αναφορά σε όνομα, το βρίσκεις στη λίστα και βρίσκεις και τη θέση του ονόματος και την βάζεις στο τελικό opcode και είσαι έτοιμος, για το επόμενο στοιχείο.
Ilias95 Δημοσ. 4 Σεπτεμβρίου 2017 Μέλος Δημοσ. 4 Σεπτεμβρίου 2017 Ευχαριστώ πολύ solarpower, αυτό έκανα τελικά!
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα