Differences

This shows you the differences between two versions of the page.

Link to this comparison view

iocla:teme:tema-3 [2022/05/26 10:08]
cristian.vijelie [Task-ul 2 - Mașina cu Stivă (25p)]
— (current)
Line 1: Line 1:
-====== Tema 3  - POLI Cat Invasion ====== 
  
-  * Deadline: 31.05.2022 
-  * Data publicării:​ 11.05.2022 
-  * Responsabili:​ 
-      * [[ ilinca.strutu@gmail.com ​           | Ilinca Struțu ​        ]] 
-      * [[ grecubogdan@hotmail.com ​           | Bogdan Grecu          ]] 
-      * [[ cristianvijelie@gmail.com ​         | Cristian Vijelie ​     ]] 
- 
-  * Actualizări:​ 
-     * 11.05.2022 - postare temă 
-===== Enunț ===== 
- 
-Sursee și prietenii ei au reușit, cu ajutorul vostru, să cucerească Facultatea de Automatică și Calculatoare. Noua lor misiune este să conducă tot campusul și să traverseze Dambovița ca să ajungă în Regie. Noii membrii ai echiei, Luna și Mushu, vor să apeleze la cunoștintele voastre în limbaj de asamblare. 
-==== Task-ul 1 - Noduri (25p) ==== 
- 
-Sursee dorește să găseasca drumul până în Rectorat ca să vadă si ea vestitul OZN. Ea știe prin ce clădiri trebuie să treacă dar lista a fost amestecată. Ajutați-o să ordoneze lista prin conectarea elementelor care inițial erau alăturate. 
- 
-Trebuie să implementați funcția cu semnătura ''​struct node* sort(int n, struct node* node);''​ din fișierul task1.asm, care "​leagă"​ nodurile din listă în ordine crescătoare. 
-Funcția primește numărul de noduri și adresa vectorului și întoarce adresa primului nod din lista rezultată. 
- 
-Structura unui nod este: 
-    struct node { 
-        int val; 
-        struct node* next; 
-    }; 
- 
-și, inițial, câmpul **next** este setat la **NULL**. 
- 
-Antetul funcției este:  
-<code c> struct node* sort(int n, struct node* node); </​code> ​ 
- 
-Semnificația argumentelor este: 
-  * **n** numărul de noduri 
-  * **node** adresa vectorului ce trebuie sortat 
- 
-Funcția returneaza adresa primului nod din lista ordonată. 
- 
-=== Precizări: === 
-  * n >= 1 
-  * secvența conține numere consecutive distincte începand cu 1 (ex: 1 2 3 ...) 
-  * structura vectorulului NU trebuie modificată (interschimbarea nodurilor este interzisă) 
-  * sortarea trebuie facută in-place 
-  * este permisă folosirea unor structuri auxiliare, atâta timp cât, nodurile listei rezultate sunt cele din vectorul inițial 
-  * NU este permisă folosirea funcției **qsort** din libc 
- 
-=== Exemplu === 
- 
-Inițial: 
- 
-^ Adresă ​   ^ Valoare ​  ^ Next      ^ 
-| 0x32      | 2         | NULL      | 
-| 0x3A      | 1         | NULL      | 
-| 0x42      | 3         | NULL      | 
- 
-Apelul funcției **sort** întoarce **0x3A** (adresa nodului cu valoarea 1) și vectorul va arăta astfel: 
- 
-^ Adresă ​   ^ Valoare ​  ^ Next      ^ 
-| 0x32      | 2         | 0x42      | 
-| 0x3A      | 1         | 0x32      | 
-| 0x42      | 3         | NULL      | 
- 
- 
-<note tip> 
-Pentru implementarea sortării vă puteți inspira din [[ https://​www.geeksforgeeks.org/​selection-sort/​ | Selection Sort]] 
-</​note>​ 
- 
-<​html>​ 
-<a style="​color:​ white; font-weight:​ bold;" href="​https://​imgur.com/​a/​2O4h25j">​Sursee va saluta :​))</​a>​ 
-</​html>​ 
- 
- 
-==== Task-ul 2 - Mașina cu Stivă (25p) ==== 
- 
-Mushu trebuie să ajungă la Leu, dar este împiedicat de portarul cel rău de la Precis. Acesta îi pune în față o [[ https://​en.wikipedia.org/​wiki/​Stack_machine | Mașină cu stivă ]], adică o mașina care știe să folosească doar stiva, prin instrucțiuni de tip **push** și **pop**, pentru a lucra cu memoria. Provocarea lui Mushu este să implementeze 2 funcții pe această mașină: 
- 
-=== CMMMC === 
- 
-Prima funcție este ''​int cmmmc(int a, int b)'',​ care calculează cel mai mic multiplu comun a 2 numere, date ca parametru. 
- 
-<note important>​ 
-Se garantează că rezultatul înmulțirii lui a și b încape pe 4 bytes 
-</​note>​ 
- 
-Antetul funcției este: 
-<code c> int cmmmc(int a, int b); </​code> ​ 
- 
-Cele două argumente sunt numerele cărora trebuie să le aflăm cel mai mic multiplu comun. 
- 
-Funcția returneaza cel mai mic multiplu comun al celor două numere. 
- 
-=== Paranteze === 
- 
-A doua funcție este ''​int par(int str_length, char *str)'',​ care verifică daca o secvență de paranteze este corectă. Aceasta primește un șir care contine **doar paranteze rotunde** si lungimea șirului, și intoarce 1, dacă secvența e corectă, sau 0, dacă secvența e greșită. 
- 
-Antetul funcției este: 
-<code c> int par(int str_length, char *str); </​code> ​ 
- 
-Semnificația argumentelor este: 
-  * **str_length** numărul de noduri 
-  * **str** adresa șirului de paranteze 
- 
-Funcția returneaza 0 daca parantezarea nu este corectă și 1 daca parantezarea e corectă. 
- 
-== Exemplu == 
-  * Pentru secvența <​nowiki>​((()())(()))</​nowiki>,​ rezultatul va fi 1 
-  * Pentru secvența <​nowiki>​(())((</​nowiki>,​ rezultatul va fi 0 
- 
-<note warning>​Nu aveti voie sa folositi intructiunile din familia mov (mov, cmov, stos, lods, etc), leave si enter. Toate operatiile de transfer din si in memorie / registre trebuie realizate folosind **push** si **pop**</​note>​ 
- 
- 
-<​html>​ 
-<a style="​color:​ white; font-weight:​ bold;" href="​https://​imgur.com/​a/​VTluNvE">​Lui Mushu nu ii plac temele</​a>​ 
-</​html>​ 
- 
- 
-==== Task-ul 3 - Sortare de cuvinte (25p) ==== 
- 
-Luna a mers împreună cu Sursee până în Rectorat dar acum trebuie sa ajungă în Regie. Luna are de completat un rebus folosind cuvintele unui text și vă roagă să o ajutați prin a sorta cuvintele în funcție de lungime ca să îi fie mai ușor. ​ 
- 
-Pentru acest task veți avea de separat un text în cuvinte dupa niște delimitatori și, după aceea, să sortați aceste cuvinte folosind funcția qsort. Sortarea se va face întâi după lungimea cuvintelor și în cazul egalitații se va sorta lexicografic. 
- 
-Va trebui să implementați 2 funcții cu semnăturile ''​void get_words(char *s, char <​nowiki>​**words</​nowiki>,​ int number_of_words);''​ și ''​void sort(char <​nowiki>​**words</​nowiki>,​ int number_of_words,​ int size);''​ din fișierul task3.asm. 
- 
-<note important>​Scopul task-ului acesta este să folosiți funcții din biblioteca standard C. Dacă există ceva în libc ce va poate ajuta, folosiți cu incredere!</​note>​ 
- 
-Antetul primei funcții este: 
-<code c> void get_words(char *s, char **words, int number_of_words);​ </​code> ​ 
- 
-Semnificația argumentelor este: 
-  * **s** textul din care extragem cuvintele 
-  * **words** vectorul de string-uri în care se salvează cuvintele găsite 
-  * **number_of_words** numărul de cuvinte 
- 
-Atenție, funcția **nu** returnează nimic, cuvintele se salveaza in vectorul words! 
- 
-Antetul celei de-a doua funcții este: 
-<code c> void sort(char **words, int number_of_words,​ int size); </​code> ​ 
- 
-Semnificația argumentelor este: 
-  * **words** vectorul de cuvinte ce trebuie sortat 
-  * **number_of_words** numărul de cuvinte 
-  * **size** dimensiunea unui cuvânt 
- 
-Atenție, funcția **nu** returnează nimic, sortarea se face in-place! 
- 
-=== Precizări === 
- 
-  * lungimea textului este mai mica decat 1000; 
-  * vectorul de cuvinte va avea maxim 100 de cuvine a 100 de caractere fiecare; 
-  * delimitatorii pe care trebuie sa ii luati in calcul sunt: spatiu( ), virgula(,), punct(.), endline (\n) 
-  * nu aveti voie sa folositi alta metoda de sortare in afara de **qsort**. In cazul in care veti folosi alta metoda punctajul pe acest task se va pierde; 
-  ​ 
-=== Exemplu === 
- 
-    number_of_words:​ 9 
-    s: "Ana are 27 de mere, si 32 de pere." 
-    dupa apelul get_words: words = ["​Ana",​ "​are",​ "​27",​ "​de",​ "​mere",​ "​si",​ "​32",​ "​de",​ "​pere"​] 
-    dupa apelul sort: words = ["​27",​ "​32",​ "​de",​ "​de",​ "​si",​ "​Ana",​ "​are",​ "​mere",​ "​pere"​] 
- 
-<note tip> 
-Pentru mai multe informatii despre qsort puteti accesa linkul: [[ https://​man7.org/​linux/​man-pages/​man3/​qsort.3.html | qsort ]] 
-</​note>​ 
- 
-<​html>​ 
-<a style="​color:​ white; font-weight:​ bold;" href="​https://​imgur.com/​a/​gDsOTHY">​Luna va felicita ca ati ajuns pana aici</​a>​ 
-</​html>​ 
- 
-==== Task-ul 4 - CPUID (15p) ==== 
- 
-Acum că pisicile au cucerit toată Universitatea Politehnică,​ vor să se relaxeze aflând câteva detalii despre procesoare. 
- 
-''​cpuid''​ este o instrucțiune specială a procesoarelor care folosesc arhitectura x86, sau derivate, care permite aflarea unor informații despre procesorul pe care se execută această instrucțiune. ​ 
- 
-Instrucțiunea cpuid nu primește parametri, ci se execută în funcție de conținutul registrului eax și, în anumite situații, a registrului ecx. Informațiile date ca răspuns sunt stocate în registrele eax, ebx, ecx, edx. Semnificația rezultatelor este documentată în specificația ​ producătorilor de procesoare x86, [[https://​web.archive.org/​web/​20120625025623/​http://​www.intel.com/​Assets/​PDF/​appnote/​241618.pdf | Intel]] si [[https://​www.amd.com/​system/​files/​TechDocs/​25481.pdf | AMD]]. 
- 
-Vi se cere sa aflați, folosind cpuid, următoarele informații despre procesorul vostru: 
-  * Manufacturer ID-ul (4p) 
-  * dacă procesorul folosește [[https://​en.wikipedia.org/​wiki/​Advanced_Programmable_Interrupt_Controller | APIC]] (1p) 
-  * dacă este suportata instrucțiunea [[https://​en.wikipedia.org/​wiki/​RDRAND | RDRAND]] (1p) 
-  * în cazul în care procesorul este de tip //Intel//, dacă suportă setul de instrucțiuni [[ https://​en.wikipedia.org/​wiki/​Intel_MPX | MPX]] (2p) 
-  * în cazul în care procesorul este de tip //AMD//, dacă suportă setul de instrucțiuni [[https://​en.wikipedia.org/​wiki/​X86_virtualization#​AMD_virtualization_.28AMD-V.29 | SVM]] (3p) 
-  * dimensiunea liniei de cache de nivel 2 (4p) 
-  * dimensiunea cache-ului de nivel 2, **pentru un singur nucleu** (bonus - 5p) 
- 
-Implementarea se va realiza în fișierul `task4.asm`. 
- 
-=== Precizări === 
- 
-  * Checker-ul va verifica ce tip de procesor este prezent și va verifica output-ul funcțiilor voastre in funcție de prezența componentelor cerute pe sistem (dacă procesorul vostru este Intel și nu are MPX, se va aștepta ca rezultatul pentru MPX sa fie 0) 
-  * Checker-ul va emula celălalt procesor, cu **toate componentele cerute**, folosind ''​qemu-i386''​. 
-  * Implementarea trebuie să poată verifica și componentele specifice Intel, și cele specifice AMD, în funcție de ce tip de procesor e detectat. 
-  * Informatii despre cache-ul de nivelul 2 se pot obtine folosind EAX=0x80000006,​ EAX=0x2 sau EAX=0x04. Folosind EAX=0x80000006 se poate afisa o dimensiune de maxim 512KB. Pentru dimensiuni mai mari, trebuie folosit EAX=0x2, care implica parsarea registrelor EAX, EBX, ECX, EDX, astfel: AL indica e cate ori trebuie apelat CPUID cu EAX=0x2, pentru a obtine date valide. Bit-ul 31 din fiecare registru indica daca contine date valide (valoarea 0) sau nu (valoarea 1). Daca un registru contine date valide, acesta va contine cate o valoare pe un byte, cu o anumita specificatie. Specificatia fiecarui byte poate fi gasita [[ https://​c9x.me/​x86/​html/​file_module_x86_id_45.html | aici ]], la sectiunea **INPUT EAX = 2:**. 
-  * Pentru EAX = 0x4, puteti consulta [[ https://​www.intel.com/​content/​dam/​www/​public/​us/​en/​documents/​manuals/​64-ia-32-architectures-software-developer-vol-2a-manual.pdf | documentatia Intel]]. 
-  * **Pentru linia de cache e suficent EAX = 0x80000006** 
-==== Task-uri bonus ==== 
- 
-Ca task-uri bonus, aveți de ales din următoarele:​ 
-  * Assembly pe 64 de biti (5p) 
-  * Sintaxa AT&T (10p) 
-  * Instructiuni vectoriale (15p) 
-  * Instructiuni speciale: RDRAND, RDTSC (10+p) 
-  * Apeluri de sistem (10p) 
-  * Floating point (15p) 
-  * Altele - vor fi adaugate pe parcurs 
- 
-<​html>​ 
-<a style="​color:​ white; font-weight:​ bold;">​Tunetele s-au oprit, au fost inlocuite de lene</​a>​ 
-</​html>​ 
- 
-<note important>​Cerințele task-urilor bonus și punctarea lor se pot găsi în fișierele task_*.md, din cadrul folderului fiecarui task.</​note>​ 
- 
-===== Trimitere și notare ===== 
- 
-Temele vor fi incarcate pe platforma de [[https://​gitlab.cs.pub.ro/​iocla/​tema-3 | Gitlab]] a facultatii sau pe platforma [[https://​examen-test.upb.ro/​mod/​assign/​view.php?​id=40 | Moodle]] experimentala. 
- 
-Pentru incarcarea pe Gitlab, va trebui sa faceti un fork al [[https://​gitlab.cs.pub.ro/​iocla/​tema-3 | repository-ului]] temei, pe care veti lucra. Puteti lucra direct pe branch-ul **master** al fork-ului, sau puteti face un nou branch pe fork, apoi sa creati un Pull Request spre **master**. In cazul variantei cu Pull Request, puteti cere review unuia dintre responsabilii temei, pentru a se uita pe cod si a va spune daca exista probleme. 
- 
-<note important>​Faceti branch-ul pe forkul facut din repository-ul temei. Fork-ul trebuie sa fie privat</​note>​ 
- 
-In cazul realizarii temei pe Gitlab, fiecare commit va duce la verificarea automata a temei. 
- 
-<note warning>​Puteti cere review pe cod pana la inceputul ultimei saptamani</​note>​ 
- 
-<note warning>​Review-ul nu va include si detalii depsre cum trebuie sa implementati cerintele. Va viza, in principal, coding style-ul</​note>​ 
- 
-A doua optiune este sa folositi checker-ul local, folosind comanda ''​sudo ./​local.sh''​. Asta va va reproduce mediul de testare de pe Gitlab pe masina voastra, si va verifica tema. Apoi, puteti incarca tema pe [[https://​examen-test.upb.ro/​mod/​assign/​view.php?​id=40 | Moodle]], sub forma de arhiva .zip. Tema va fi apoi verificata. 
- 
-<note important>​Din folderul temei (tema3/), executand comanda ''​make zip'',​ se va crea arhiva cu structura asteptata de checker. Fisierul README, daca este adaugat, trebuie sa fie scris in Markdown si sa aiba extensia .md</​note>​ 
- 
-<note tip>​Puteti gasi procesul de rezolvare si incarcare al temelor [[https://​github.com/​Jokeswar/​vmchecker-next/​wiki/​Student-Handbook | aici]]</​note>​ 
- 
-Punctajul final acordat pe o temă este compus din: 
-  * punctajul obținut prin testarea automată de pe vmchecker - 90p 
-  * coding style - 10p 
-  * bonus - maxim 50p 
- 
-<​note>​ Punctajul maxim este 150p </​note>​ 
- 
-Rezultatul rularii checker-ului se poate vedea pe Moodle. Tot acolo va aparea si corectarea facuta de catre asistenti. 
- 
-<note tip>​Fisierul README.md este optional. Va incurajam sa detaliati implementarile folosind comentarii punctuale in cod (nu comentati fiecare linie, ci blocuri de cod). Scrieti in README daca considerati necesar sa detaliati mai mult implementarea sau daca aveti feedback legat de tema</​note>​ 
- 
-<​note>​ 
-Coding style-ul constă în: 
-   * prezența comentariilor în cod 
-   * scrierea unui cod lizibil 
-   * indentarea consecventă 
-   * utilizarea unor nume sugestive pentru label-uri 
-   * scrierea unor linii de cod/README de maxim 80-100 de caractere 
-</​note>​ 
- 
-<​note>​ 
-Pentru detalii despre coding style parcurgeți acest document: 
-[[http://​www.sourceformat.com/​pdf/​asm-coding-standard-brown.pdf | coding style]] 
-</​note>​ 
- 
-<note warning> 
-Temele care nu trec de procesul de asamblare (build) nu vor fi luate în considerare. 
-</​note>​ 
- 
-<note warning> 
-Vă reamintim să parcurgeți atât secțiunea de [[:​iocla:​reguli-notare##​depunctari_teme|depunctări]] cât și [[:​iocla:​reguli-notare##​realizarea_temelor|regulamentul de realizare a temelor]]. 
-</​note>​ 
- 
-===== Precizări suplimentare ===== 
- 
-<note warning>​Toate task-urile vor fi realizate in limbajul de asamblare x86 (32 de biti), in afara de cazurile cand se specifica explicit alt limbaj.</​note>​ 
- 
-===== FAQ ====== 
-  * **Q**: Este permisă utilizarea variabilelor globale? 
-      * **A**: Da 
- 
-===== Resurse ===== 
-  * [[ https://​ocw.cs.pub.ro/​courses/​iocla/​reguli-notare | Reguli si notare ]] 
iocla/teme/tema-3.1653548910.txt.gz · Last modified: 2022/05/26 10:08 by cristian.vijelie
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0