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/22 16:55] 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 **main.cpp** și adăugați următorul cod: | + | 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 296: | Line 313: | ||
Dați **Clean Project** și apoi **Build Project**. În acest moment vi s-a generat un fișier ***.asm**, dar care nu va apărea în Visual Studio.\\ | Dați **Clean Project** și apoi **Build Project**. În acest moment vi s-a generat un fișier ***.asm**, dar care nu va apărea în Visual Studio.\\ | ||
- | Pentru a vizualiza fișierul în cauză, dați click dreapta pe **Solution //nume_proiect//** și selectați **Open Folder in File Explorer**. În folderul **//nume_proiect//\Debug** veți găsi fișierul **Source.asm** corespunzător programului scris în C. După cum puteți observa, acesta conține codul de asamblare intercalat cu comentarii în care este prezentat codul original. | + | Pentru a vizualiza fișierul în cauză, dați click dreapta pe **Solution //nume_proiect//** și selectați **Open Folder in File Explorer**. În directoare **//nume_proiect//\Debug** veți găsi fișierul **Source.asm** corespunzător programului scris în C. După cum puteți observa, acesta conține codul de asamblare intercalat cu comentarii în care este prezentat codul original. |
+ | <note important> | ||
+ | Există două directoare cu numele ''Debug'': unul aferent soluției și altul aferent proiectului. Alegeți directorul ''Debug'' aferent proiectului. | ||
+ | </note> | ||
==== 3. [20p] SASM: walkthrough ==== | ==== 3. [20p] SASM: walkthrough ==== | ||
Line 339: | 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> | ||