====== Tema 2 ======
* Deadline Soft: Vineri, 19.12.2015 23:55
* Deadline Hard: Miercuri, 6.01.2016 23:55
* Data publicării: 3.12.2015, 00:09
* Data ultimei modificări: 18.12.2015, 22:57
* iResponsabili:
* [[catalinvasile92@gmail.com|Cătălin Vasile]]
* [[razvan.nitu1305@gmail.com|Răzvan Niţu]]
===== Enunț =====
Să se implementeze un program în limbaj de asamblare care simulează calculator cu următoarele operaţii posibile:
* ''%%+%%'' (adunare)
* ''%%*%%'' (înmulţire)
* ''%%<<%%'' (shiftare la stânga)
* ''%%>>%%'' (shiftare la dreapta)
Numerele sunt cu semn şi pot depăşii dimensiunea unui operand cu care poate lucra arhitectura folosită la laborator (i386).
===== Implementare =====
Implementarea efectivă trebuie să înceapă iniţial din fişierul **calc.asm**.\\
Execuţia programului începe cu un apel la **convert_to_native()**. Această funcţie are următoarea semnătură:
==== void convert_to_native(char *a_str, char *b_str, void *a, void *b) ====
**a_str** şi **b_str** reprezintă string-urile date ca input pentru a simboliza operanzii A şi B. Voi va trebui să îi convertiţi pe aceştia la o altă reprezentare la adresele **a** şi **b**. Primii 4 bytes vor fi semnul numărului, urmat de **lungime**a numărului reprezentat tot pe 4 bytes şi o serie **lungime** bytes care reprezintă efectiv numărul în little endian.
/* Exemple: */
/* Dacă a_str ar fi “-2FC23”, >>a<< ar fi reprezentat în felul următor: */
unsigned char actual_number[] = [0x23, 0xFC, 0x02];
unsigned int *a_int = a;
unsigned char *a_char = a_int + 2;
a_int[0] = 0xFFFFFFFF; /* all ones */
a_int[1] = 3;
memcpy(a_char, actual_number, length);
/* Dacă a_str ar fi “2FC23”, >>a<< ar fi reprezentat în felul următor: */
unsigned char actual_number[] = [0x23, 0xFC, 0x02];
unsigned int *a_int = a;
unsigned char *a_char = a_int + 2;
a_int[0] = 0x00000000; /* all zeros */
a_int[1] = 3;
memcpy(a_char, actual_number, length);
Reprezentarea efectivă şi calculele se vor face pe o reprezentare pozitivă (**actual_number**, din exemplul anterior, va fi pozitiv mereu după cum reiese şi din exemplu).
Părţile de **length** şi **sign** vor fi gata setate înainte să vă fie apelată funcţia **convert_to_native()**.
**Dacă nu se respectă şi foloseşte această reprezentare la calculele efective, punctajul pe temă va fi anul complet.**
Când conversia a fost terminată, vi se va apela funcţia do_operation(), care are următoarea semnătură:
==== void do_operation(void *a, void *b, char *operation) ====
În această funcţie trebuie să implementaţi efectiv execuţia operaţilor. **operation** este un string cu operatorul primit din linie de comandă.\\
Rezultatul trebuie depus în **a**. Atât **a**, cât şi **b**, au spaţiu suficient pentru execuţia calculelor. Urmăriţi implementarea lui **allocate_vectors()** dacă vreţi să înțelegeți mai în detaliu ce înseamnă “suficient”.
Avem următoarele precizări în privinţa algoritmilor folosiţi pentru operaţii:
- Cum specifică şi regulamentul: algoritmul **trebuie** să **NU** fie copiat.
- Semnul operanzilor la operaţii de shiftare nu va influența cu nimic execuţia operaţiei.
- Operațiile de shiftare nu vor fi făcute cu un număr de shiftări negative.
- Operațiile de shiftare **trebuie** să folosească efectiv operațiile de shiftare (cu sau fără carry)
- Operaţia de înmulţire **trebuie** să folosească efectiv operaţia **mul** sau **imul**
- Orice încercare de trucare a acestor reguli va duce la anulare completă a punctajului pe temă.
Ultima funcţie pe care va trebui să o implementaţi se numeşte **print_number()** şi are următoarea semnătură:
==== void print_number(void *number) ====
Această funcţie primeşte un număr pe care trebuie să-l afişeze într-un format similar celui de input: caracterul **-**, dacă numărul este negativ, urmat de reprezentarea în hex big endian fără padding.
===== Rulare =====
./calc $A op $B
**op** trebuie să fie între apostrofe, pentru că bash-ul încearcă să îl interpreteze şi expandeze înainte să ajungă la programul vostru. De exemplu:
* '<<' este văzut ca redirectarea cu concatenare
* '*' este văzut ca un wildcard care se expandează la o enumerare cu fişierele din folderul curent.
Exemplu input şi output:
arcade@Arcade-PC:~/workspace/iocla_tema2 > ./calc -234FF '+' 2343
FF3402 ; memory dump la reprezentarea operandului A
4323 ; memory dump la reprezentarea operandului B
BC1102 ; memory dump la reprezentarea rezultatului
-211BC ; afişarea “normală” a rezultatului, asemănătoare inputului
===== Trimitere și notare =====
Temele vor trebui încărcate pe platforma [[https://vmchecker.cs.pub.ro/ui/#IOCLA|vmchecker]] (în secțiunea IOCLA) și vor fi testate automat. Arhiva încărcată va fi o arhivă ''.zip'' care trebuie să conțină:
* fișierele sursă ce conțin implementarea temei: ''Makefile'', ''main.c'', ''macro.c'' și orice fișier de tip ''.asm'' şi/sau ''*.inc''
* fișier ''README'' ce conține descrierea implementării
În {{http://elf.cs.pub.ro/asm/res/teme/iocla-tema2-resurse.zip|arhiva de resurse a temei}} puteți folosi fișierul ''Makefile'' pentru crearea arhivei care va fi încărcată pe [[https://vmchecker.cs.pub.ro/ui/#IOCLA|vmchecker]] folosind comanda
make pack
Punctajul final acordat pe o temă este compus din:
* punctajul obținut prin testarea automată de pe vmchecker - 80%
* shiftări - 20%
* adunare - 20%
* înmulţire - 40%
* coding style - 10%. Se va ține cont de:
* claritatea codului
* indentare coerentă
* comentarii
* nume sugestive pentru label-uri
* fișier README - 10%
Temele care nu trec de procesul de asamblare (//build//) nu vor fi luate în considerare.
Mașina virtuală folosită pentru testarea temelor de casă pe vmchecker este descrisă în secțiunea [[:utile#masini-virtuale|Mașini virtuale]] din pagina de resurse.
===== Resurse ajutătoare =====
* [[laboratoare:laborator-06|Laborator 6]]: reprezentare numerică,calcule complexe
* [[laboratoare:laborator-04#breviarapelatul-in-cadrul-unei-functii|Laborator 4]]: apelarea unei funcţii, parametri pe stivă
* Secţiunea de [[:bune-practici|Bune practici]]: compilare, utilizarea funcțiilor din biblioteci pe diverse platforme, erori des întâlnite.
===== Precizări suplimentare =====
* Tema va fi implementată strict în limbaj de asamblare (cel puţin partea de TODO-uri menţionate în scheletul de cod).
* Pentru debugging funcţional puteţi folosi **gdb** sau macrourile de printare din biblioteca **io.inc**. Orice macro din io.inc salvează starea registrelor înainte de “apelarea” macro-ului. Metodele de debugging nu se limitează la aceste tool-urile, este doar o exemplificare.
* Arhiva în cauza trebuie să includă toate fişierele modificate de voi (exclusiv fişierele care vi s-au recomandat să le modificaţi, fie din enunţ sau din scheletul de cod).
* Inputul este dat în format hexa, fără prefixul **0x**, şi poate conţine si caracterul - la început pentru a simboliza că numărul este negativ.
* **Dacă nu se respectă şi foloseşte această reprezentare menţionată a numerelor la calculele efective, punctajul pe temă va fi anul complet.**
* **Dacă nu sunt respectate prevederile specificate la implementarea funcţiei do_operation() legate de implementarea algoritmilor de calcul, punctajul pe temă va fi anul complet.**
* **Încălcarea oricărei prevederi menţionate în enunţ, sau în regulamentul materiei, va fi penalizată, CEL PUŢIN, cu anularea punctajului pe această temă, chiar dacă acestea au trecut un set de teste.**
* **Mimarea respectării prevederilor menţionate în enunţ şi/sau din regulament vor avea aceleaşi penalizări ca nerespectarea lor. Cum exprimarea umană poate fi uneori ambiguă, vă recomandăm să ne puneţi întrebări pe forumul temei legate de aceste aspecte. Ne rezervăm dreptul asupra interpretării acestor prevederi.**
===== Resurse =====
Arhiva ce conține checker-ul, testele și fișierele de la care puteți începe implementarea este {{http://elf.cs.pub.ro/asm/res/teme/iocla-tema2-resurse.zip|aici}}.