diff --git a/report/images/RAM_layout.png b/report/images/RAM_layout.png new file mode 100644 index 0000000..1b1aba1 Binary files /dev/null and b/report/images/RAM_layout.png differ diff --git a/report/images/RAM_layout.svg b/report/images/RAM_layout.svg new file mode 100644 index 0000000..678e679 --- /dev/null +++ b/report/images/RAM_layout.svg @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + End of RAM + + + 0x20000000 + + data + bss Heap_Size Stack_Size + + + __initial_sp + Free + + diff --git a/report/images/Untitled Diagram.drawio b/report/images/Untitled Diagram.drawio new file mode 100644 index 0000000..8d62ffd --- /dev/null +++ b/report/images/Untitled Diagram.drawio @@ -0,0 +1 @@ +7Vtbc+I2FP41zLSdYceSLyGPIZfdtjTT5to8KlgxzgqLlQWB/vpKtnyTDHgTwCQhM5lYx5IsnXO+7xxd0rFPx/OvDE1Gf1Efkw60/HnHPutACEDPFX+kZJFKPFsJAhb6qlIhuA7/w0poKek09HFcqcgpJTycVIVDGkV4yCsyxBh9qVZ7oqT61QkKsCG4HiJiSu9Dn49SaQ8eFfJvOAxG2ZeBd5y+GaOssppJPEI+fSmJ7POOfcoo5enTeH6KiVReppf73xf3ZPDd+/rHP/EPdNv/8+byrpt2dvEzTfIpMBzxV3c9H0b88f7h7vLqidyh2zk9WQy6wFFz44tMYdgX+lNFyviIBjRC5LyQ9hmdRj6W3VqiVNQZUDoRQiCEz5jzhXIGNOVUiEZ8TNRbPA/5v7L5F1eVHkpvzuaq56SwyAoRZ4tSI1l8KL8rmiWlrF06PzkpzR/WKFPVi+mUDfGKep7yacQCvLI/mLuMwBqmYyxGKRoyTBAPZ9XRIeX0QV6vMKx4ULb9CTs7Vpt2BiUrFzZfY2dQsXJh9P2xcz2iem+0s2r6Nw3FuKGliNjNLKho2O1Z1S7SgalWhbecMIYWpWoTWSFe8R1Y/U7GfhcN62fhoXDWdASF6+Y6aeTNq2wxQ2Sq9BmzoRDIZ1m0Lm8HA8Ph2YiOH6dCD/2XUcjx9QQlBn8Rca/qtjnRS796ohG/QOOQyAl+w2SGeThE6oXyfIFtu49IGESiMBT+hpnshjP6PQ86Scfik2EUiJJXlG4SMHWd3IebuuwMM47nJX8ynS5761aNBI5V+aWIiCBzsFEpGnqak22Mj0CrfPQR4g7Ikql1hPRWPmpq55WjLEG1Az0ixtv3w5l4DHiiq1QkISVzPKRm7v2YyuSqX8AuF2VNZ0DhXqhMcIDblyOSIvcs61UMPO24+jEh3tAQoDmE5zVD0Kkp92ywnp504gkIimPldTWcUyazbRGMDY++uBWKcYBrUozlmhTjbo1i7APFvJFiYNOcp1WKgQbFhDkgrQyBj0xHegn8zwWAORvgKOCjXwSUf5UTqyeLD4ZfPUGAvbYTBPuA3ubordWgZYJ3eTLd1rrUMrDbx0EYmbYnJJzEeD24lnh+U70uR8iRlkKDGoRYNQjZXnxz20TIq5b0VqetJf3ysNVk62ZX8a12lLB3YMKN27le00dt2rnRSinJbKCHxpL2VGYiFxvNspR3sgGyffZ2rIbsre+ybQ7VreY3H4G9e00XJ60mONA7sPeO7Lyrja5Voyyx9wx0ku3oGTwQcWmjSNsmqtuJBrtcaMJW0+gqQK2VAN16mvRWoqw/IYLaCZGtm3JDJ1dOz639zqZOolboTMvahKVkoqZvPHW7zyYT7HTjaPN4djwtsTo2t33dXa6K7aNW4fyavKq9g+4VcbRBwLWdNgMuMCMuw3zKROA7EeIra9Ue8G9X59e3g5tylQ8GTFs/l687j4E1yHS2FmjNvb4HHBuKF3rgWhKUaPCUEipymbOIRhKyTyEhmshIe6RWRYZETtSLcej7ZNkeYpUDtmUWqC9EoZn/1O2zw61Zxdx2+HxWcTSwuDXbAzu1ir1HSen7XDVm9zv3PIplw1wfxcD6KAYMp3nvUQxo6aVbQ5e7jWK2GcUu6Sejy/xudxbEemZusVu6NIPYpzOKrWUWrtt2DHMMo9QcaJxHfsPTi707AvZaPwK263YfSiq2MsctLq0R/MTNK2z6cmgufi0xF6uhbd4OrWRc+wksLTnMY9K6uzHbQ5a59K1B1h1iIXoUyoNWV6YSOAhjwV7x6vuPJVF3+c/yW1VrexUpTZLaJDe2m7YBaZuweQuYtlh6NGq2sNMWs6V3vswmjmoCm+vjEwMH2g2BA7aGHOew2pWX+/TLurDt9a5j5gqfLoHTs2q4vQROFIt/W0yPQop//rTP/wc= \ No newline at end of file diff --git a/report/images/isPalindrome.png b/report/images/isPalindrome.png new file mode 100644 index 0000000..8c5864e Binary files /dev/null and b/report/images/isPalindrome.png differ diff --git a/report/report.pdf b/report/report.pdf index c31ca4c..b7aab26 100644 Binary files a/report/report.pdf and b/report/report.pdf differ diff --git a/report/report.tex b/report/report.tex index 71ddeff..7fbd52a 100644 --- a/report/report.tex +++ b/report/report.tex @@ -8,7 +8,7 @@ % Document configuration \newcommand{\ClassName}{Μικροεπεξεργαστές και Περιφερειακά} -\newcommand{\DocTitle}{Εργασία Ι} +\newcommand{\DocTitle}{1η Εργασία} \newcommand{\InstructorName}{Παπαευσταθίου Ιωάννης} \newcommand{\InstructorMail}{ygp@ece.auth.gr} \newcommand{\CurrentDate}{\today} @@ -33,7 +33,80 @@ %\listoftables \section{Εισαγωγή} - +Στην παρούσα εργασία το ζητούμενο είναι η υλοποίηση μιας ρουτίνας σε γλώσσα \eng{assemblly ARM,} που να ελέγχει αν ένα αλφαριθμητικό είναι παλίνδρομο, αλλά και η ενσωμάτωση αυτής σε ένα πρόγραμμα σε γλώσσα \eng{C.} +Για την εργασία χρησιμοποιήσαμε το εργαλείο \eng{Keil uVision} και μιας και δεν αντιμετωπίσαμε κάποιο ιδιαίτερο πρόβλημα, η αναφορά αυτή θα αναλωθεί κυρίως στην υλοποίηση και τον έλεγχο του προγράμματος. +Τον κώδικα της εργασίας αλλά και της παρούσας αναφοράς μπορείτε να βρείτε ακόμα στο προσωπικό \href{https://git.hoo2.net/hoo2/micro_assign_1}{αποθετήριο της εργασίας}. + +\section{Παραδοτέα} +Στο παραδοτέο \eng{.zip} αρχείο μπορείτε να βρείτε: +\begin{itemize} + \item Το αρχείο \textbf{\eng{main.c}} που περιέχει όλο τον ζητούμενο κώδικα της εργασίας. + \item Το αρχείο \textbf{\eng{report.pdf}} που είναι παρούσα αναφορά. + \item Τον κατάλογο \textbf{\eng{Keil}} που περιέχει το \eng{project} στο \eng{Keil} που χρησιμοποιήσαμε.\\ + Στο \eng{project} αυτό περιέχονται επιπλέων οι ρυθμίσεις καθώς και τα αρχεία από τη βιβλιοθήκη \eng{CMSIS} που χρειάστηκαν για την ορθή αρχικοποίηση και αλληλεπίδραση με τον επεξεργαστή. +\end{itemize} + +\section{Υλοποίηση} +Η υλοποίηση του ελέγχου αν ένα αλφαριθμητικό είναι παλίνδρομο έγινε σε δύο συναρτήσεις, την \eng{\textit{isPalindrome()}} και την \eng{\textit{strLength()},} που λειτουργεί ως βοηθητική συνάρτηση. +Οι συναρτήσεις αυτές είναι υλοποιημένες σε γλώσσα \eng{assemblly} αλλά η κλήση τους από το κυρίως πρόγραμμα δεν διαφέρει καθόλου από την κλήση μιας οποιασδήποτε άλλης συνάρτησης σε γλώσσα \eng{C.} +Για τον λόγο αυτό δεν θα ασχοληθούμε περαιτέρω με το κύριο πρόγραμμα (συνάρτηση \eng{main).} + +\subsection{Συνάρτηση \eng{\textit{isPalindrome()}}} +\WrapFigure{0.42}{r}{fig:isPalindrome}{isPalindrome.png}{Διάγραμμα ροής της συνάρτησης \eng{\textit{isPalindrome()}}} +Για τη συνάρτηση αυτή χρησιμοποιήσαμε ένα απλό \eng{O(n)} σειριακό αλγόριθμο, ο οποίος απαιτεί το μήκος του αλφαριθμητικού εισόδου προτού εισέλθει στον κύριο βρόχο επανάληψης. +Για να βρούμε το μήκος χρησιμοποιούμε μια ξεχωριστή συνάρτηση. +Αυτή την υλοποιήσαμε από την αρχή ώστε να μην χρειαστεί να χρησιμοποιηθεί η συνάρτηση \eng{\textit{strlen()}} της \eng{\textit{libc}.} + +\par Όπως φαίνεται και στο διάγραμμα του σχήματος \ref{fig:isPalindrome}, στον κύριο βρόχο της συνάρτησης χρησιμοποιούμε δύο απαριθμητές \eng{i, j} χρησιμοποιώντας τους καταχωρητές \eng {R1, R2} αντίστοιχα και ένα δείκτη στη διεύθυνση του αλφαριθμητικού χρησιμοποιώντας τον καταχωρητή \eng{R0.} +Ο ένας δείκτης εκκινεί από την αρχή του αλφαριθμητικού και ο άλλος από το τέλος. +Σε κάθε επανάληψη διαβάζουμε από το αλφαριθμητικό τα \eng{src[i]} και \eng{src[j]} και ελέγχουμε αν είναι ίσα. +Αν δεν είναι τότε το αλφαριθμητικό δεν είναι παλίνδρομο. +Αν είναι τότε μεταθέτουμε το \eng{i} μία θέση δεξιά και το \eng{j} μία θέση αριστερά και επανεκτελούμε τον βρόχο. +Ο βρόχος συνεχίζει όσο το \eng{i} είναι μικρότερο από το \eng{j.} +Αν το \eng{i} γίνει ίσο ή μεγαλύτερο από το \eng{j,} τότε ο βρόχος τερματίζει. +Σε αυτή την περίπτωση το αλφαριθμητικό είναι παλίνδρομο. + +\par Αν το αλφαριθμητικό έχει μηδενικό μήκος, τότε ο βρόχος δεν θα εκτελεστεί ούτε μία φορά και η συνάρτηση θα επιστρέψει ότι το αλφαριθμητικό είναι παλίνδρομο. +Έχουμε κάνει δηλαδή την θεώρηση ότι \textbf{\textit{τα μηδενικού μήκους αλφαριθμητικά είναι παλίνδρομα}}, καθώς είναι τα ίδια είτε τα κοιτάς από μπροστά είτε τα κοιτάς από πίσω. +Στην περίπτωση που η είσοδος της συνάρτησης είναι εκτός πεδίου ορισμού, δηλαδή ο \eng{NULL pointer,} τότε η συνάρτηση επιστρέφει ψευδές αποτέλεσμα. +Ο έλεγχος του δείκτη εισόδου γίνεται στην αρχή της συνάρτησης πριν καν γίνει η κλήση για το μήκος, προστατεύοντας έτσι κάποιο \eng{exception} από το \eng{dereference} του δείκτη στην εντολή \eng{LDR.} + +\subsection{Συνάρτηση \eng{\textit{strLength()}}} +Η υλοποίηση της \eng{\textit{strLength()}} είναι επίσης ένας σειριακός αλγόριθμος. +Εδώ χρησιμοποιούμε τον καταχωρητή \eng{R1} ώς δείκτη στο αλφαριθμητικό και με αυτόν κάνουμε ανάγνωση της μνήμης, αυξάνοντάς τον ταυτόχρονα μετά από κάθε ανάγνωση. +Η συνάρτηση επιστρέφει τον αριθμό των αναγνώσεων που χρειάστηκαν μέχρι να λάβουμε το νούμερο '0', το οποίο σηματοδοτεί το τέλος του αλφαριθμητικού. + +\par Ομοίως και εδώ κάνουμε έλεγχο της εισόδου ώστε αυτή να μην είναι ο \eng{NULL pointer.} +Φυσικά αυτό στη δική μας περίπτωση δεν είναι απαραίτητο καθώς υπάρχει ο αντίστοιχος έλεγχος στην \eng{\textit{isPalindrome()}} προτού την κλήση. +Παρόλα αυτά το θεωρούμε καλή πρακτική, καθώς αυτό καθιστά την \eng{\textit{strLength()}} πιο ολοκληρωμένη συνάρτηση και μια χρήση της στο μέλλον δεν θα προκαλέσει εκπλήξεις. + +\subsection{Εγγραφή του αποτελέσματος στη μνήμη} +\WrapFigure{0.23}{l}{fig:ram_layout}{RAM_layout.png}{Διάταξη της μνήμης} +Η συνάρτηση \eng{\textit{isPalindrome()}} αφού εκτελεστεί, επιστρέφει μια τιμή στον \eng{caller.} +Στα ζητούμενα όμως της εργασίας ήταν η συνάρτηση αυτή να γράφει το αποτέλεσμα και σε μία θέση μνήμης της επιλογής μας. +Αυτό υπό κανονικές συνθήκες είναι ανεπίτρεπτο. +Για τα πλαίσια όμως της εργασίας προσπαθήσαμε να ανταπεξέλθουμε με ένα σχετικά ασφαλή τρόπο. + +\par Όπως φαίνεται και στο σχήμα \ref{fig:ram_layout}, o συνδέτης \eng{(linker)} του εργαλείου \eng{keil} δεν τοποθετεί τον \eng{SP} στο τέλος της μνήμης. +Για την ακρίβεια, χρησιμοποιώντας δύο τιμές από το \eng{configuration} του \eng{startup} αρχείου για το μέγεθος του σωρού και της στοίβας, υπολογίζει τη τιμή \eng{\textit{\textbf{\_\_initial\_sp}}.} +Αυτή την τιμή χρησιμοποιεί έπειτα σαν πρώτο όρισμα στο \eng{vector table} και άρα αυτή την τιμή έχει ο \eng{SP} κατά την εκκίνηση. + +\par Έχοντας αυτό σαν δεδομένο μπορούμε να επιλέξουμε μια τιμή στην ελεύθερη περιοχή, έχοντας πάντα στο μυαλό μας ότι αλλάζοντας τα δεδομένα του προγράμματος η τιμή αυτή μπορεί να αλλάξει. +Στη δική μας περίπτωση η επιλεγμένη τιμή ήταν το \eng{\textbf{0x20001000}.} +Φυσικά αυτή η τιμή μπορεί να αλλάξει εύκολα αλλάζοντας απλώς την τιμή από το \eng{\textbf{\#define RESULT}.} +Μάλιστα αυτό είναι και κάτι που προτρέπουμε κάνει ο οποιονδήποτε θέλει να τρέξει τον κώδικά μας, ώστε να βεβαιωθεί πως η τιμή αυτή είναι στην ασφαλή ζώνη. + + +\section{Έλεγχος} +Για τον έλεγχο της ορθότητας του κώδικα χρησιμοποιήσαμε τον \eng{debuger} του εργαλείου κάνοντας ταυτόχρονη χρήση του \eng{simulator.} +Καθώς η εκφώνηση ανέφερε την δημιουργία μιας \eng{main,} θεωρήσαμε ότι είναι ευκαιρία να χρησιμοποιήσουμε την \eng{main} για να επιτύχουμε ένα είδους \eng{debug-mode unit testing.} +Έτσι στο εσωτερικό της δηλώσαμε αλφαριθμητικά για έλεγχο και για αυτά καλέσαμε την \eng{\textit{isPalindrome()}.} +Έπειτα εκτελώντας τον \eng{debuger} καταφέραμε να κάνουμε την όποια αποσφαλμάτωση που χρειάστηκε. + +\section{Επίλογος} +Θεωρούμε ότι η παρούσα εργασία ήταν μια καλή πρώτη επαφή με την μίξη κώδικα \eng{C - assemblly,} καθώς και των όποιων απαιτήσεων από μεριάς \eng{assemblly} ώστε αυτή να είναι συμβατή με το πρότυπο που ακολουθεί ο \eng{compiler (AAPCS).} +Η μόνη παραφωνία σε αυτή τη συνεργασία ήταν η επιλογή μιας ελεύθερης θέσης μνήμης για την επιστροφή του αποτελέσματος. +Αυτό γιατί μέχρι τη σύνταξη του παρόντος δεν βρήκαμε τρόπο να διαβάσουμε από διαφορετικό αρχείο(πχ το \eng{main.c}) την τιμή \eng{\_\_initial\_sp,} ώστε η επιλογή της θέσης να αυτοματοποιηθεί. % References % ============================