This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
laboratoare:laborator-02 [2015/10/23 16:49] razvan.deaconescu [2.[20p] Microsoft Visual Studio: from C to assembly] |
laboratoare:laborator-02 [2015/10/23 19:05] (current) razvan.deaconescu [4. [40p] C: GOTOs] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Laborator 02: Toolchain ====== | ====== Laborator 02: Toolchain ====== | ||
| + | |||
| În acest laborator, vom trece prin fiecare nivel de procesare a unui limbaj de nivel înalt și prin toolchain-ul pe care îl vom folosi de acum încolo. | În acest laborator, vom trece prin fiecare nivel de procesare a unui limbaj de nivel înalt și prin toolchain-ul pe care îl vom folosi de acum încolo. | ||
| ===== C basics: GOTOs ===== | ===== C basics: GOTOs ===== | ||
| + | |||
| Un concept mai puțin abordat în tutoriale de C este instrucțiunea **goto**. | Un concept mai puțin abordat în tutoriale de C este instrucțiunea **goto**. | ||
| Prin instrucțiunea **goto**, un program poate sări în puncte intermediare în cadrul unei funcții. | Prin instrucțiunea **goto**, un program poate sări în puncte intermediare în cadrul unei funcții. | ||
| - | Aceste puncte intermediare se numesc **label**-uri (etichete).\\ | + | Aceste puncte intermediare se numesc **label**-uri (etichete). |
| Un exemplu de cod: | Un exemplu de cod: | ||
| <code c> | <code c> | ||
| Line 23: | Line 26: | ||
| } | } | ||
| </code> | </code> | ||
| + | |||
| Programul execută un job prin **work()**. În caz că mai sunt alte joburi neterminate, programul sare la labelul **do_some_work**.\\ | Programul execută un job prin **work()**. În caz că mai sunt alte joburi neterminate, programul sare la labelul **do_some_work**.\\ | ||
| **do_some_work** este punctul din program în care începe procesarea unui nou job. Acesta e marcat printr-un nume urmat de **:**. | **do_some_work** este punctul din program în care începe procesarea unui nou job. Acesta e marcat printr-un nume urmat de **:**. | ||
| Line 237: | Line 241: | ||
| Un tool interesant pentru a observa cum se traduce codul C în limbaj de asamblare este **Compiler Explorer**. | Un tool interesant pentru a observa cum se traduce codul C în limbaj de asamblare este **Compiler Explorer**. | ||
| - Intrați pe [[http://gcc.godbolt.org/|Compiler Explorer]]. | - Intrați pe [[http://gcc.godbolt.org/|Compiler Explorer]]. | ||
| - | - Încărcați programul "sum over array" de la exemple, adică selectați combobox-ul ''Name''. | + | - Încărcați programul "sum over array" din exemple (accesibile folosind intrările ''Source: Examples'' și ''Name: sum over array''). |
| - Asigurați-vă că **x86 gcc 4.8.2** este selectat la **Compiler:**. | - Asigurați-vă că **x86 gcc 4.8.2** este selectat la **Compiler:**. | ||
| - Selectați **Intel syntax**. Acesta este un format mai ușor de digerat și mai asemănător formatului acceptat de NASM. | - Selectați **Intel syntax**. Acesta este un format mai ușor de digerat și mai asemănător formatului acceptat de NASM. | ||
| Line 246: | Line 250: | ||
| - Treceți, pe rând, prin compilatoarele corespunzătoare următoarelor arhitecturi: ARM, ARM64, AVR, PowerPC. Se poate observa cum codul generat diferă de la o arhitectură la alta. | - Treceți, pe rând, prin compilatoarele corespunzătoare următoarelor arhitecturi: ARM, ARM64, AVR, PowerPC. Se poate observa cum codul generat diferă de la o arhitectură la alta. | ||
| - Mai încercați și următoarele compilatoare: **clang** și **icc**. După cum se poate observa, deși este același cod C și aceeași arhitectură, codul generat diferă. Acest lucru se întâmplă pentru că fiecare compilator poate avea o strategie de optimizare și generare de cod diferită. | - Mai încercați și următoarele compilatoare: **clang** și **icc**. După cum se poate observa, deși este același cod C și aceeași arhitectură, codul generat diferă. Acest lucru se întâmplă pentru că fiecare compilator poate avea o strategie de optimizare și generare de cod diferită. | ||
| - | + | ||
| <note> | <note> | ||
| [[http://clang.llvm.org/|clang]] este un compilator open-source de C\C++. Adesea este folosit în IDE-uri datorită mesajelor de eroare de compilare foarte sugestive pe care le produce. | [[http://clang.llvm.org/|clang]] este un compilator open-source de C\C++. Adesea este folosit în IDE-uri datorită mesajelor de eroare de compilare foarte sugestive pe care le produce. | ||
| Line 254: | Line 258: | ||
| **icc** este compilatorul de C\C++ al celor de la compania Intel. | **icc** este compilatorul de C\C++ al celor de la compania Intel. | ||
| </note> | </note> | ||
| + | |||
| + | ---- | ||
| + | |||
| + | Scrieți în zona ''Code editor'' următoarea secvență de cod:<code> | ||
| + | int simple_fn(void) | ||
| + | { | ||
| + | int a = 1; | ||
| + | a++; | ||
| + | return a; | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | Observați codul în limbaj de asamblare atunci când opțiunile de compilare (''Compiler options'') sunt ''-m32'', respectiv atunci când opțiunile de compilare sunt ''-m32 -O2''. Observați ce efect au opțiunile de optimizare asupra codului în limbaj de asamblare generat. | ||
| ==== 2.[20p] Microsoft Visual Studio: from C to assembly ==== | ==== 2.[20p] Microsoft Visual Studio: from C to assembly ==== | ||
| Line 265: | Line 282: | ||
| </note> | </note> | ||
| - | Creați un fișier nou în **cadrul proiectului**, numit ''main.cpp'' și adăugați următorul cod în fișier. Puteți da click dreapta pe intrarea ''Source files'' din partea dreapta a ecranului ''Visual Studio'' și apoi puteți folosi ''Add -> New Item''. | + | Pentru a adăuga un fișier nou în cadrul proiectului mergeți cu mouse-ul în zona ''Solution Explorer'' (din partea dreapta sus a ecranului) și apoi folosiți click dreapta pe intrarea ''Source files'', apoi folosiți ''Add'' și apoi, după caz, ''New Item'' sau ''Existing Item''. Adăugați un fișier nou în **cadrul proiectului**, numit ''main.cpp'' și adăugați următorul cod în fișier: |
| <code c> | <code c> | ||
| #define DATA_LEN 100 | #define DATA_LEN 100 | ||
| Line 342: | Line 359: | ||
| ==== 4. [40p] C: GOTOs ==== | ==== 4. [40p] C: GOTOs ==== | ||
| - | Implementați algoritmii de mai jos în C **fără a folosi apeluri de funcţii (exceptând //scanf()// şi //printf()//), else, for, while, do {} while; și construcțiile cu if nu pot conține return**. Adică va trebui să folosiți multe instrucțiuni ''goto''. | + | <note important> |
| - | - maximul dintr-un vector [20p] | + | |
| - | - căutare binară [20p] | + | Când scrieți cod cu etichete (label-uri) țineți cont de următoarele recomandări de indentare: |
| + | * Nu indentați etichetele (label-urile). "Lipiți-le" de marginea din stânga a ecranului de editare. | ||
| + | * O etichetă este singură pe linie. Nu există cod după etichetă. | ||
| + | * Nu țineți cont de indentare în indetarea codului. Codul trebuie indendat în același mod și cu etichete și fără etichete. | ||
| + | * Puneți o linie liberă înaintea linie care conține o etichetă. | ||
| + | |||
| + | </note> | ||
| + | |||
| + | Pentru algoritmii de mai jos scrieți cod în C **fără** a folosi: | ||
| + | * apeluri de funcţii (exceptând //scanf()// şi //printf()//) | ||
| + | * else | ||
| + | * for | ||
| + | * while | ||
| + | * do {} while; | ||
| + | * construcțiile ''if'' care conțin return | ||
| + | |||
| + | Adică va trebui să folosiți ''if'' și multe instrucțiuni ''goto''. | ||
| + | |||
| + | **[20p]** Implementați maximul dintr-un vector folosind cod C și constrângerile de mai sus. | ||
| + | |||
| + | **[20p]** Implementați căutare binară folosind cod C și constrângerile de mai sus. | ||
| <note warning> | <note warning> | ||
| Reiterăm ideea că scenariile de utilizare ale instrucțiunii ''goto'' sunt limitate. Exercițiile acestea au valoare didactică pentru a vă acomoda cu instrucțiuni de salt (//jump//) pe care le vom folosi în dezvoltarea în limbaj de asamblare. | Reiterăm ideea că scenariile de utilizare ale instrucțiunii ''goto'' sunt limitate. Exercițiile acestea au valoare didactică pentru a vă acomoda cu instrucțiuni de salt (//jump//) pe care le vom folosi în dezvoltarea în limbaj de asamblare. | ||
| + | </note> | ||
| + | |||
| + | <note tip> | ||
| + | Pentru scrierea de programe puteți folosi orice editor indicat pe Desktop sau IDE-urile Code::Blocks sau Visual Studio. | ||
| + | |||
| + | Pentru compilarea/rularea codului puteți folosi IDE-urile Code::Blocks sau Visual Studio sau puteți folosi linia de comandă ca mai jos. | ||
| + | |||
| + | Pentru a compila un fișier cod sursă C/C++ în linia de comandă folosind Visual Studio, urmați pașii: | ||
| + | - Deschideți butonul de start, selectați ''All apps'' , apoi mergeți la litera ''V'', selectați directorul ''Visual Studio 2015'' și alegeți opțiunea ''Visual Studio x86 Native Command Prompt''. | ||
| + | - Accesați directorul în care aveți codul sursă. | ||
| + | - Folosiți comanda<code> | ||
| + | cl <nume-fisier>.cpp | ||
| + | </code> unde ''<nume-fisier>'' este numele fișierului. | ||
| + | - Rulați executabilul obținut folosind comanda<code> | ||
| + | .\nume-fisier | ||
| + | </code> unde ''<nume-fisier>'' este numele fișierului. | ||
| + | |||
| + | /* | ||
| + | Pentru a compila un fișier cod sursă C/C++ în linia de comandă folosind GCC, urmați pașii: | ||
| + | - Deschideți un Command Prompt. | ||
| + | - Adăugați calea către GCC la ''PATH'' folosind comanda<code> | ||
| + | PATH=%PATH%;C:\MinGW\bin | ||
| + | </code> | ||
| + | - Folosiți comanda<code> | ||
| + | g++ <nume-fisier>.cpp | ||
| + | </code> unde ''<nume-fisier>'' este numele fișierului. Sau puteți folosi<code> | ||
| + | gcc <nume-fisier>.c | ||
| + | </code> pentru fișier cod sursă scris în C (nu în C++). | ||
| + | - Rulați executabilul obținut folosind comanda<code> | ||
| + | .\nume-fisier | ||
| + | </code> unde ''<nume-fisier>'' este numele fișierului. | ||
| + | |||
| + | */ | ||
| + | |||
| </note> | </note> | ||