Differences

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

Link to this comparison view

iocla:laboratoare:laborator-01 [2020/10/16 09:15]
ionut.mihalache1506 [Sistemul binar]
iocla:laboratoare:laborator-01 [2022/03/02 21:19] (current)
teodor_stefan.dutu [Exerciții]
Line 7: Line 7:
 Înainte de a începe lucrul cu limbajul de asamblare, este necesar să ne familiarizăm cu sistemele binar și hexazecimal și cu modalitățile de conversie între ele. Înainte de a începe lucrul cu limbajul de asamblare, este necesar să ne familiarizăm cu sistemele binar și hexazecimal și cu modalitățile de conversie între ele.
  
-<​note ​tip> +<​note>​ Pentru reprezentarea numerelor în binar vom folosi prefixul 0b, iar pentru cele în hexazecimal vom folosi 0x. </​note>​
-Pentru reprezentarea numerelor în binar vom folosi prefixul ​**0b**, iar pentru cele în hexazecimal vom folosi ​**0x**. +
-</​note>​ +
  
 ==== Sistemul binar ==== ==== Sistemul binar ====
  
-În **sistemul binar** (baza 2), valorile sunt reprezentate ca un șir de 0 și 1. Fiecare cifră din șir reprezintă un bit, iar un grup de 8 biți formează un **octet** (**byte**). Un grup de 4 biți poartă denumirea de **nibble**, sau **half-byte**.+În **sistemul binar** (baza 2), valorile sunt reprezentate ca un șir de 0 și 1. Fiecare cifră din șir reprezintă un bit, iar un grup de 8 biți formează un octet (byte). Un grup de 4 biți poartă denumirea de **nibble**, sau **half-byte**.
  
 === Operații cu valori reprezentate în binar === === Operații cu valori reprezentate în binar ===
Line 26: Line 23:
 == Operatori pe valori binare == == Operatori pe valori binare ==
  
-  - **Inversare** (**NOT**): se inversează fiecare bit. Exemplu: INV(0b10011010) = 0b01100101 +  - **Inversare (NOT)**: se inversează fiecare bit. Exemplu: INV(0b10011010) = 0b01100101 
-  - **Și logic** (**AND**): se efectuează operația '​și'​ între biții de pe aceleași poziții din operanzi. Exemplu: 0b1001 AND 0b0111 = 0b0001 +  - **Și logic (AND)**: se efectuează operația '​și'​ între biții de pe aceleași poziții din operanzi. Exemplu: 0b1001 AND 0b0111 = 0b0001 
-  - **Sau logic** (**OR**): se efectuează operația '​sau'​ între biții de pe aceleași poziții din operanzi. Exemplu: 0b1001 OR 0b0111 = 0b1111 +  - **Sau logic (OR)**: se efectuează operația '​sau'​ între biții de pe aceleași poziții din operanzi. Exemplu: 0b1001 OR 0b0111 = 0b1111 
-  - **Sau exclusiv** (**XOR**): dacă biții de pe aceleași poziții din operanzi au valori egale, bitul rezultat are valoarea 0, altfel are valoarea 1. Exemplu: 0b1001 XOR 0b0111 = 0b1110+  - **Sau exclusiv (XOR)**: dacă biții de pe aceleași poziții din operanzi au valori egale, bitul rezultat are valoarea 0, altfel are valoarea 1. Exemplu: 0b1001 XOR 0b0111 = 0b1110
  
 == Deplasări (Shifts) == == Deplasări (Shifts) ==
Line 37: Line 34:
 Deplasările logice dreapta/​stânga presupun mutarea cu o poziție a fiecărui bit. Cum rezultatul trebuie să fie pe același număr de biți ca valoarea inițială, primul bit este pierdut, iar spațiul gol este completat cu bitul 0. Deplasările logice dreapta/​stânga presupun mutarea cu o poziție a fiecărui bit. Cum rezultatul trebuie să fie pe același număr de biți ca valoarea inițială, primul bit este pierdut, iar spațiul gol este completat cu bitul 0.
  
-{{:​iocla:​laboratoare:​left-logical-shift.png?200|}} {{:​iocla:​laboratoare:​right-logical-shift.png?200|}} | +{{:​iocla:​laboratoare:​left-logical-shift.png|Deplasare logică la stânga}} 
-| Deplasare logică la stânga ​                  | Deplasare logică la dreapta ​                  |+ 
 +{{:​iocla:​laboratoare:​right-logical-shift.png|Deplasare logică la dreapta}}
  
-Pentru explicații legate de operațiile pe biți în C urmăriți ghidul de mai jos: +Pentru explicații legate de operațiile pe biți în C urmăriți ghidul de la adresa ​[[https://​www.geeksforgeeks.org/​bitwise-operators-in-c-cpp/​|Operații pe biți în C]].
-[[https://​www.geeksforgeeks.org/​bitwise-operators-in-c-cpp/​|Operații pe biți în C]]+
  
 ==== Sistemul hexazecimal ==== ==== Sistemul hexazecimal ====
Line 52: Line 49:
   * Când câtul împărțirii devine 0, se scriu resturile în ordine inversă.   * Când câtul împărțirii devine 0, se scriu resturile în ordine inversă.
   * În cazul bazei 16, atunci când restul este mai mare decât 9 se folosesc literele a-f (10=a, 15=f)   * În cazul bazei 16, atunci când restul este mai mare decât 9 se folosesc literele a-f (10=a, 15=f)
- 
-== Exemplu: conversia numărului 113 în hexazecimal == 
- 
-  * Pas 1: 113/16 = 7, rest **1** 
-  * Pas 2: 7 / 16 = 0, rest **7** 
-  * Câtul este 0, deci putem obține numărul în hexazecimal scriind resturile în ordine inversă: **0x71** 
- 
-=== Conversia din binar/​hexazecimal în zecimal === 
- 
-Un număr convertit din baza X în baza 10 are valoarea egală cu suma produselor dintre fiecare cifră din numărul în baza X și X la puterea egală cu poziția cifrei în numărul respectiv (numărarea se face de la dreapta la stânga, începând cu 0). 
  
 == Exemplu: conversia numărului 0xD9B1 în zecimal == == Exemplu: conversia numărului 0xD9B1 în zecimal ==
  
-0xD9B1 ​<​nowiki>​=</​nowiki> ​1*16<sup>0</​sup> ​+ 11*16<sup>1</​sup> ​+ 9*16<sup>2</​sup> ​+ 13*16<sup>3</​sup>​ <​nowiki>​=</​nowiki> ​55729+0xD9B1 = 1 * 16 0 + 11 * 16 1 + 9 * 16 2 + 13 * 16 3 = 55729
  
 === Conversia intre binar și hexazecimal === === Conversia intre binar și hexazecimal ===
Line 73: Line 60:
 == Exemplu: Conversia numărului 0xD9B1 în binar == == Exemplu: Conversia numărului 0xD9B1 în binar ==
  
-  * 0x1 <​nowiki>​=</​nowiki> ​0b0001 +  * 0x1 = 0b0001 
-  * 0xB <​nowiki>​=</​nowiki> ​0b1011 +  * 0xB = 0b1011 
-  * 0x9 <​nowiki>​=</​nowiki> ​0b1001 +  * 0x9 = 0b1001 
-  * 0xD <​nowiki>​=</​nowiki> ​0b1101+  * 0xD = 0b1101
  
 Astfel, numărul obținut în binar este **0b1101100110110001**. Astfel, numărul obținut în binar este **0b1101100110110001**.
Line 83: Line 70:
  
 === La ce utilizăm reprezentarea în baza 16? === === La ce utilizăm reprezentarea în baza 16? ===
-Sistemul hexazecimal este utilizat pentru a reprezenta adresele la care se află datele în memorie și pentru a vizualiza aceste date într-un mod mai ușor de interpretat decât o secvență compusă doar din 0 și 1. 
-Imaginea de mai jos oferă un exemplu în acest sens: 
  
-| {{https://​www.digital-detective.net/​wp-content/​uploads/​2018/​08/​Hex-View.png?​700x350}} | +Sistemul hexazecimal este utilizat pentru a reprezenta adresele la care se află datele în memorie și pentru a vizualiza aceste date într-un mod mai ușor de interpretat decât o secvență compusă doar din 0 și 1Imaginea de mai jos oferă un exemplu în acest sens:
-| Hartă memorie |+
  
-În partea stângă avem adresele din memorie unde se află date. La adresa **0x0009FA08** primii 4 octeți începând cu offset-ul **0x02** sunt **0x01**, **0x00**, **0xFF**, **0xFF**Aceștia pot reprezenta un întreg pe 4 octeți, 4 caractere, 2 întregi pe 2 octeți. Folosind baza 16 putem să interpretăm datele reușind astfel să intuim ce ar putea să reprezinte acestea.+{{:​iocla:​laboratoare:​Hex-View.png?​700x350|Hartă memorie}}
  
 ==== Reprezentarea tipurilor de date ==== ==== Reprezentarea tipurilor de date ====
Line 95: Line 79:
 În memoria unui calculator o valoare este memorată pe un număr fix de biți. În funcție de arhitectură fiecare procesor poate accesa un număr maxim de biți în cadrul unei operații, acest număr de biți reprezintă dimensiunea cuvântului (**word size**). În memoria unui calculator o valoare este memorată pe un număr fix de biți. În funcție de arhitectură fiecare procesor poate accesa un număr maxim de biți în cadrul unei operații, acest număr de biți reprezintă dimensiunea cuvântului (**word size**).
  
-Dimensiunile tipurilor de date uzuale folosite în C sunt dependente atât de procesor, cât și de platforma cu ajutorul căreia a fost compilat programul (sistem de operare, compilator). ​ +Dimensiunile tipurilor de date uzuale folosite în C sunt dependente atât de procesor, cât și de platforma cu ajutorul căreia a fost compilat programul (sistem de operare, compilator). În tabelul de mai jos sunt prezentate dimensiunile tipurilor de date pe un procesor cu dimensiunea cuvântului arhitecturii de 32 de biți, în cazul în care programul este compilat folosind gcc, sub Linux.
-În tabelul de mai jos sunt prezentate dimensiunile tipurilor de date pe un procesor cu dimensiunea cuvântului arhitecturii de 32 de biți, în cazul în care programul este compilat folosind gcc, sub Linux.+
  
-^ Tip de date ^ Număr biți      ^ Număr octeți ​         +În partea stângă avem adresele din memorie unde se află date. La adresa **0x0009FA08** primii 4 octeți începând cu offset-ul **0x02** sunt **0x01**, **0x00**, **0xFF**, **0xFF**. Aceștia pot reprezenta un întreg pe 4 octeți, 4 caractere, 2 întregi pe 2 octeți. Folosind baza 16 putem să interpretăm datele reușind astfel să intuim ce ar putea să reprezinte acestea. 
-| char        | 8               ​| 1                     ​+ 
-| short       ​| 16              | 2                     ​+^Tip de date^Număr biți^Număr octeți^ 
-| int         ​| 32              | 4                     ​+|char       ​|8         ​|1           ​
-| long        | 32              | 4                     ​+|short ​     |16        |2           ​
-| long long   ​| 64              | 8                     ​+|int        |32        |4           ​
-| pointer ​    ​| 32              | 4                     ​|+|long       ​|32        |4           ​
 +|long long  |64        |8           ​
 +|pointer ​   |32        |4           ​|
  
 ==== Ordinea de reprezentare a numerelor mai mari de un octet (Little-Endian vs Big-Endian) ==== ==== Ordinea de reprezentare a numerelor mai mari de un octet (Little-Endian vs Big-Endian) ====
 +
 Pentru reprezentarea valorilor mai mari de un octet există două metode posibile, ambele folosite în practică: Pentru reprezentarea valorilor mai mari de un octet există două metode posibile, ambele folosite în practică:
 +
   * Little-Endian:​ cel mai puțin semnificativ octet este memorat primul(octeții sunt memorați în ordine inversă). Acest model este folosit de familia de procesoare Intel x86.   * Little-Endian:​ cel mai puțin semnificativ octet este memorat primul(octeții sunt memorați în ordine inversă). Acest model este folosit de familia de procesoare Intel x86.
   * Big-Endian: cel mai semnificativ octet este memorat primul.   * Big-Endian: cel mai semnificativ octet este memorat primul.
  
-**Exemplu:** Dorim să stocăm valoarea 0x4a912480 în memorie pe 32 de biți (4 octeți), începând cu adresa 0x100, folosind cele două metode:+**Exemplu**Dorim să stocăm valoarea 0x4a912480 în memorie pe 32 de biți (4 octeți), începând cu adresa 0x100, folosind cele două metode:
  
-^ Metoda ​     ^ Adresa 0x100    ^ Adresa 0x101      ^ Adresa 0x102  ^ Adresa 0x103 ^ +^Metoda ​      ​^Adresa 0x100^Adresa 0x101^Adresa 0x102^Adresa 0x103^ 
-| Little-Endian ​       | 0x80   ​| 0x24   ​| 0x91    | 0x4a | +|Little-Endian|0x80 ​       |0x24        |0x91        |0x4a        
-| Big-Endian ​          ​| 0x4a   ​| 0x91   ​| 0x24    | 0x80 |+|Big-Endian ​  ​|0x4a        |0x91        |0x24        |0x80        |
  
 ===== Pointeri în C ===== ===== Pointeri în C =====
Line 121: Line 108:
 În limbajul C un pointer este o variabilă a cărei valoare este adresa unei alte variabile. Ne putem gândi la un pointer ca un intermediar,​ și anume o variabilă care indică către o locație finală sau către un alt intermediar după cum se poate vedea în imaginea și codul de mai jos. În limbajul C un pointer este o variabilă a cărei valoare este adresa unei alte variabile. Ne putem gândi la un pointer ca un intermediar,​ și anume o variabilă care indică către o locație finală sau către un alt intermediar după cum se poate vedea în imaginea și codul de mai jos.
  
-{{https://​www.tenouk.com/​Module8_files/​cpluspointer020.png?320x180}} | +{{:iocla:​laboratoare:​cpluspointer020.png|Simple and double pointer}}
-| Simple and double pointer ​|+
  
-<​code ​c>+<​code ​cpp>
 #include <​stdio.h>​ #include <​stdio.h>​
    
Line 145: Line 131:
  
 </​code>​ </​code>​
- +==== Avantaje pointeri ​====
-=== Avantaje pointeri ===+
  
   * pointerii sunt folosiți la crearea de structuri de date complexe precum liste înlănțuite,​ arbori, grafuri, tabele de dispersie, etc.   * pointerii sunt folosiți la crearea de structuri de date complexe precum liste înlănțuite,​ arbori, grafuri, tabele de dispersie, etc.
Line 153: Line 138:
   * putem să avem ca parametri pentru funcții alte funcții, șiruri de caractere, structuri de date complexe   * putem să avem ca parametri pentru funcții alte funcții, șiruri de caractere, structuri de date complexe
  
-=== Dezavantaje pointeri ===+==== Dezavantaje pointeri ​====
  
   * un pointer care nu este inițializat,​ dar este folosit într-un program duce la **segmentation fault** prin accesarea unei zone de memorie restricționate   * un pointer care nu este inițializat,​ dar este folosit într-un program duce la **segmentation fault** prin accesarea unei zone de memorie restricționate
Line 160: Line 145:
  
 În C se poate defini un pointer către oricare dintre tipurile de date care există în limbaj cât și pentru **void**. Un void pointer diferă de un pointer către un tip de date explicit prin faptul că un void pointer **NU** poate fi folosit în operații cu pointeri, void neavând o dimensiune clară. Un exemplu de bază unde se folosesc pointerii și operațiile cu pointeri este alocarea și parcurgerea unui tablou de valori: În C se poate defini un pointer către oricare dintre tipurile de date care există în limbaj cât și pentru **void**. Un void pointer diferă de un pointer către un tip de date explicit prin faptul că un void pointer **NU** poate fi folosit în operații cu pointeri, void neavând o dimensiune clară. Un exemplu de bază unde se folosesc pointerii și operațiile cu pointeri este alocarea și parcurgerea unui tablou de valori:
-<​code ​c>+ 
 +<​code ​cpp>
 #include <​stdio.h>​ #include <​stdio.h>​
 #include <​stdlib.h>​ #include <​stdlib.h>​
 + 
 #define ARR_LENGTH 5 #define ARR_LENGTH 5
 + 
 int main() int main()
 { {
    int *arr, i;    int *arr, i;
-   + 
    arr = (int *)malloc(sizeof(int) * ARR_LENGTH);​    arr = (int *)malloc(sizeof(int) * ARR_LENGTH);​
    // arr = (int *)calloc(ARR_LENGTH,​ sizeof(int));​    // arr = (int *)calloc(ARR_LENGTH,​ sizeof(int));​
 + 
    for (i = 0; i < ARR_LENGTH; ++i) {    for (i = 0; i < ARR_LENGTH; ++i) {
        /*        /*
Line 180: Line 166:
        ​printf("​arr[%d] = %d: ", i, *(arr + i));        ​printf("​arr[%d] = %d: ", i, *(arr + i));
    }    }
 + 
    ​free(arr);​    ​free(arr);​
    ​return 0;    ​return 0;
 } }
-</​code>​ 
  
 +</​code>​
 Pointerii oferă o flexibilitate mare în ce privește accesul la memorie. Mai jos este un exemplu în acest sens care verifică dacă un sistem este little sau big endian, folosind cast între diverse tipuri de pointeri. Pointerii oferă o flexibilitate mare în ce privește accesul la memorie. Mai jos este un exemplu în acest sens care verifică dacă un sistem este little sau big endian, folosind cast între diverse tipuri de pointeri.
-<code c> 
-#include <​stdio.h>​ 
  
 +<code cpp>
 +#include <​stdio.h>​
 + 
 int main() int main()
 { {
     int v = 0x00000001;     int v = 0x00000001;
     unsigned char *first_byte = (unsigned char *)&v;     unsigned char *first_byte = (unsigned char *)&v;
-    ​+ 
     if (*first_byte == 0x01)     if (*first_byte == 0x01)
         printf("​little-endian\n"​);​         printf("​little-endian\n"​);​
     else     else
         printf("​big-endian\n"​);​         printf("​big-endian\n"​);​
 + 
     return 0;     return 0;
 } }
-</​code>​ 
  
 +</​code>​
 ===== Exerciții ===== ===== Exerciții =====
  
 <note important>​ <note important>​
-În cadrul laboratoarelor vom folosi repository-ul de git al materiei IOCLA - https://​github.com/​systems-cs-pub-ro/​iocla. Repository-ul este clonat pe desktop-ul mașinii virtuale. Pentru a-l actualiza, folosiți comanda ''​git pull origin master''​ din interiorul directorului în care se află repository-ul (''​~/​Desktop/​iocla''​).Recomandarea este să îl actualizați cât mai frecvent, înainte să începeți lucrul, pentru a vă asigura că aveți versiunea cea mai recentă. +În cadrul laboratoarelor vom folosi repository-ul de git al materiei IOCLA - ([[https://​github.com/​systems-cs-pub-ro/​iocla|https://​github.com/​systems-cs-pub-ro/​iocla]]). Repository-ul este clonat pe desktop-ul ​[[https://​ocw.cs.pub.ro/​courses/​iocla/​utile#​masina_virtuala_de_linux|mașinii virtuale]]. Pentru a-l actualiza, folosiți comanda ''​%%git pull origin master%%''​ din interiorul directorului în care se află repository-ul (~/​Desktop/​iocla).Recomandarea este să îl actualizați cât mai frecvent, înainte să începeți lucrul, pentru a vă asigura că aveți versiunea cea mai recentă. Dacă doriți să descărcați repository-ul în altă locație, folosiți comanda ''​%%git clone https://​github.com/​systems-cs-pub-ro/​iocla ${target}%%''​. Pentru mai multe informații despre folosirea utilitarului ''​%%git%%'',​ urmați ghidul de la [[https://​gitimmersion.com|Git Immersion]].
- +
-Dacă doriți să descărcați repository-ul în altă locație, folosiți comanda ''​git clone https://​github.com/​systems-cs-pub-ro/​iocla ${target}''​. +
-Pentru mai multe informații despre folosirea utilitarului ''​git'',​ urmați ghidul de la [[https://​gitimmersion.com]].+
 </​note>​ </​note>​
  
Line 218: Line 202:
  
 a. Din decimal în binar și hexazecimal:​ a. Din decimal în binar și hexazecimal:​
 +
   * 121   * 121
   * 18446   * 18446
  
 b. Convertiți în zecimal: b. Convertiți în zecimal:
 +
   * 0b1100010111010010   * 0b1100010111010010
   * 0xBB29   * 0xBB29
  
 c. Din hexazecimal în binar: c. Din hexazecimal în binar:
 +
   * 0x5E   * 0x5E
   * 0x4A01   * 0x4A01
  
 d. Din binar în hexazecimal:​ d. Din binar în hexazecimal:​
 +
   * 0b01111101   * 0b01111101
   * 0b1000110000011111   * 0b1000110000011111
  
-<​note ​important> +<​note ​tip> În rezolvarea exercițiilor următoare NU aveți voie să modificați semnătura funcțiilor pe care trebuie să le implementați. Veți porni de la un fișier inițial și puteți adăuga oricâte funcții și fișiere auxiliare considerați,​ dar aveți în vedere că dacă adăugați fișiere noi va trebui să modificați Makefile-ul,​ să creați un nou Makefile sau să compilați manual. Recomandarea este să utilizați fișierul pus deja la dispoziția voastră fără a adăuga altele noi.
-În rezolvarea exercițiilor următoare ​**NU** aveți voie să modificați semnătura funcțiilor pe care trebuie să le implementați. Veți porni de la un fișier inițial și puteți adăuga oricâte funcții și fișiere auxiliare considerați,​ dar aveți în vedere că dacă adăugați fișiere noi va trebui să modificați Makefile-ul,​ să creați un nou Makefile sau să compilați manual. Recomandarea este să utilizați fișierul pus deja la dispoziția voastră fără a adăuga altele noi. +
 Pentru compilare și execuție puteți folosi: Pentru compilare și execuție puteți folosi:
-  * make build +make build 
-  ​* ​make run +make run 
-  ​* ​make clean(opțional,​ pentru a șterge fișierele obiect și executabilul) +make clean(opțional,​ pentru a șterge fișierele obiect și executabilul) </​note>​
-</​note>​+
  
 ==== 2. Lungime și egalitate cu operații pe biți ==== ==== 2. Lungime și egalitate cu operații pe biți ====
 +
 Veți rezolva exercițiul plecând de la fișierul **len_xor.c** aflat în directorul **2-len_xor**. Veți rezolva exercițiul plecând de la fișierul **len_xor.c** aflat în directorul **2-len_xor**.
  
-Pentru un șir de caractere dat, să se afișeze:\\+Pentru un șir de caractere dat, să se afișeze: 
   * lungimea șirului de caractere   * lungimea șirului de caractere
-  * adresa fiecărui caracter de pe poziția ​**i** care este egal cu caracterul de poziția ​**i** **+** **2****^****i** (dacă ​**i** **+** **2****^****i** depășește dimensiunea șirului de caractere se va folosi operația modulo)+  * adresa fiecărui caracter de pe poziția i care este egal cu caracterul de poziția i + 2^i (dacă i + 2^i depășește dimensiunea șirului de caractere se va folosi operația modulo) 
 Folosiți cât de mult posibil operații cu pointeri și operații pe biți! Folosiți cât de mult posibil operații cu pointeri și operații pe biți!
-<note important>​Nu folosiți în rezolvare funcții precum strlen, sizeof, pow, si nu verificați egalitatea folosind ==. De asemenea, nu accesați elementele șirului sub forma s[i].</​note>​ 
-<​note>​ 
-Pentru șirul de caractere "​aac":​ 
-  * length = 3 
-  * Address of a: 0x564c364482a0 
-  * Address of a: 0x564c364482a1 
  
-Pentru șirul de caractere "​ababababacccbacbacbacbacbabc":​ +<​note>​ Nu folosiți în rezolvare funcții precum strlen, sizeof, pow, si nu verificați egalitatea folosind ​==. De asemenea, nu accesați elementele șirului sub forma s[i]. </​note>​
-  * length ​28 +
-  * Address of b: 0x563f0da6f2a1 +
-  * Address of a: 0x563f0da6f2a2 +
-  * Address of c: 0x563f0da6f2a9 +
-  * Address of a: 0x563f0da6f2b0 +
-  * Address of b: 0x563f0da6f2b2 +
-  * Address of b: 0x563f0da6f2b5 +
-  * Address of c: 0x563f0da6f2b7 +
-  * Address of a: 0x563f0da6f2b9+
  
-**Adresele de mai sus sunt orientative!** +<note tip> Pentru șirul de caractere “aac”:​ 
-</​note>​+ 
 +length = 3 
 +Address of a: 0x564c364482a0 
 +Address of a: 0x564c364482a1 
 + 
 +Pentru șirul de caractere “ababababacccbacbacbacbacbabc”:​ 
 + 
 +length = 28 
 +Address of b: 0x563f0da6f2a1 
 +Address of a: 0x563f0da6f2a2 
 +Address of c: 0x563f0da6f2a9 
 +Address of a: 0x563f0da6f2b0 
 +Address of b: 0x563f0da6f2b2 
 +Address of b: 0x563f0da6f2b5 
 +Address of c: 0x563f0da6f2b7 
 +Address of a: 0x563f0da6f2b9 
 + 
 +**Adresele de mai sus sunt orientative!** </​note>​
  
 ==== 3. Oglindirea unui șir de caractere ==== ==== 3. Oglindirea unui șir de caractere ====
 +
 Veți rezolva exercițiul plecând de la fișierul **mirror.c** aflat în directorul **3-mirror**. Veți rezolva exercițiul plecând de la fișierul **mirror.c** aflat în directorul **3-mirror**.
  
-Folosind operații cu pointeri implementați un program în C care inversează un șir de caractere. Funcția ​//mirror// trebuie să realizeze rotirea datelor din șirul de caractere **in-place** (la ieșirea din funcție, șirul dat ca intrare va conține șirul inversat). +Folosind operații cu pointeri implementați un program în C care inversează un șir de caractere. Funcția ​''​%%mirror%%'' ​trebuie să realizeze rotirea datelor din șirul de caractere **in-place** (la ieșirea din funcție, șirul dat ca intrare va conține șirul inversat). 
-<​note ​important>Nu accesați elementele șirului sub forma s[i].</​note>​ + 
-<​note>​ +<​note>​ Nu accesați elementele șirului sub forma s[i]. </​note>​ 
-  ​* ​mirror("AnaAreMere") = "ereMerAanA" + 
-  ​* ​mirror("asdfghjl") = "ljhgfdsa" +<​note ​tip>  
-  ​* ​mirror("qwerty") = "ytrewq+mirror(AnaAreMere) = ereMerAanA” 
-</​note>​+ 
 +mirror(asdfghjl) = ljhgfdsa” 
 + 
 +mirror(qwerty) = ytrewq” </​note>​
  
 ==== 4. Rotații ==== ==== 4. Rotații ====
-Veți rezolva exercițiul plecând de la fișierul ​**rotations.c** aflat în directorul ​**4-rotations**.+ 
 +Veți rezolva exercițiul plecând de la fișierul rotations.c aflat în directorul 4-rotations.
  
 Implementați în C rotație stânga și rotație dreapta pentru numere întregi pe 32 de biți. Implementați în C rotație stânga și rotație dreapta pentru numere întregi pe 32 de biți.
-<note tip> 
-Operația de rotire (numită și deplasare circulară) este similară cu cea de deplasare, singura diferență fiind aceea că spațiul gol generat de deplasare este înlocuit cu bitul eliminat. 
  
-| {{:​iocla:​laboratoare:​left-rotate.png?​200|}} | {{:​iocla:​laboratoare:​right-rotate.png?​200|}} | +<​note ​tipOperația de rotire (numită și deplasare circulară) este similară cu cea de deplasare, singura diferență fiind aceea că spațiul gol generat de deplasare este înlocuit cu bitul eliminat.
-| Rotire la stânga ​                     | Rotire la dreapta ​                     | +
-</note>+
  
-<​note>​ +Exemplu rotație ​**stânga** cu **un** bit: 
-  ​rotate_left(0x80000000,​ 1) = 1 + 
-  ​rotate_right(0x00000001,​ 16) = 65536+{{:​iocla:​laboratoare:​left-logical-rotation.png|Rotație logică la stânga}}
 </​note>​ </​note>​
 +
 +<​note> ​
 +rotate_left(0x80000000,​ 1) = 1
 +rotate_right(0x00000001,​ 16) = 65536 </​note>​
  
 ==== 5. Par binar și impar hexa ==== ==== 5. Par binar și impar hexa ====
-Veți rezolva exercițiul plecând de la fișierul **odd_even.c** aflat în directorul **5-odd_even**. 
  
-Să se parcurgă un tablou ​de întregi pe 32 de biți folosind operații cu pointeri și să se afișeze în binar numerele pare și în hexazecimal numerele impare.+Veți rezolva exercițiul plecând de la fișierul odd_even.c aflat în directorul 5-odd_even. 
 + 
 +Să se parcurgă un vector ​de întregi pe 32 de biți folosind operații cu pointeri și să se afișeze în binar numerele pare și în hexazecimal numerele impare.
  
-<note important>​În rezolvare folosiți operații pe biți oriunde este posibil!</​note>​ 
 <​note>​ <​note>​
-Pentru vectorul: **214**, **71**, **84**, **134**, **86**, programul va afișa:+În rezolvare folosiți operații pe biți oriunde este posibil! 
 +</​note>​
  
-  - 0b11010110 +<​note>​ 
-  ​- ​0x00000047 +Pentru vectorul: 214, 71, 84, 134, 86, programul va afișa: 
-  ​- ​0b01010100 + 
-  ​- ​0b10000110 +<​code>​ 
-  ​- ​0b01010110+0b11010110 
 +0x00000047 
 +0b01010100 
 +0b10000110 
 +0b01010110 
 +</​code>​
 </​note>​ </​note>​
 +
 +===== Soluții =====
 +
 +Soluțiile pentru exerciții sunt disponibile [[https://​elf.cs.pub.ro/​asm/​res/​laboratoare/​lab-01-sol.zip|aici]].
 +
 +
iocla/laboratoare/laborator-01.1602828943.txt.gz · Last modified: 2020/10/16 09:15 by ionut.mihalache1506
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