Acest repository conține metode de gestiune a memoriei folosind tehnici din cadrul cursului de Arhitectura Sistemelor de Calcul (ASC).
- Cazul unidimensional (
1D_memory.s) – gestionarea memoriei de stocare ca un spațiu liniar . - Cazul bidimensional (
2D_memory.s) – extinderea gestionării memoriei pe două dimensiuni .
- Prezentare generală
- Structura proiectului
- Cerințe și formate de input/output
- Compilare și rulare
- Exemple de utilizare
- Note administrative
- Resurse și referințe
Acest proiect implementează un modul de gestionare a dispozitivului de stocare (hard-disk sau SSD) pentru un sistem de operare minimal. Sunt două variante:
-
Memorie unidimensională:
- Capacitate totală fixă de 8 MB, împărțită în blocuri de câte 8 kB (în implementarea demonstrativă, un bloc de 8 kB este modelat ca 8 B).
- Fiecare fișier trebuie stocat contigu și ocupă un număr întreg de blocuri (rotunjire în sus).
- Operații suportate:
- ADD (alocare fișier)
- GET (interogare interval de blocuri pentru un descriptor)
- DELETE (ștergere fișier)
- DEFRAGMENTATION (reordonarea blocurilor pentru a compacta spațiul liber)
-
Memorie bidimensională:
- Dispozitiv de stocare privit ca o matrice de 8 MB × 8 MB, împărțită în blocuri de 8 kB fiecare (în demonstrație, 8 B).
- Fiecare fișier trebuie stocat pe linii succesive, tot contigu.
- Operații similare cu cazul unidimensional plus o operație suplimentară:
- CONCRETE (scanare a unui director local, determinare descriptor și dimensiune pentru fiecare fișier, apoi tratare ca un ADD)
Ambele cazuri trebuie implementate în limbaj de asamblare x86 (fișiere .s), astfel încât evaluarea să fie automată și să respecte formatul cerut.
- 1D_memory.s
Conține codul pentru partea unidimensională (ADD, GET, DELETE, DEFRAGMENTATION). - 2D_memory.s
Conține codul pentru partea bidimensională (ADD, GET, DELETE, DEFRAGMENTATION și CONCRETE). - input.txt
Exemple de fișiere cu seturi de operații care pot fi folosite pentru a testa codul.
-
Structura memoriei
- Capacitate totală: 8 MB
- Blocuri de 8 kB → în implementarea demonstrativă, un bloc are 8 B.
- Fiecare bloc stochează descriptorul (un număr între 1 și 255) sau
0dacă este liber. - Maximum 255 fișiere active (descriptor ∈ [1..255]).
-
Codificarea operațiilor
1→ ADD2→ GET3→ DELETE4→ DEFRAGMENTATION
-
Formatul inputului
- Prima linie:
O= numărul de operații. - Pentru fiecare dintre cele
Ooperații:- Citiți un cod de operație (1..4).
- Dacă e
ADD(cod1):- Citiți
N= numărul de fișiere care urmează să fie adăugate. - Pentru fiecare dintre cele
Nfișiere, două linii consecutive:- Descriptor (întreg, între 1 și 255).
- Dimensiune în kB (întreg).
- Pentru fiecare fișier, se returnează un interval de blocuri:
unde primul
%d: (%d, %d)\n%deste descriptorul, următoarele două%dsunt blocul de start și blocul de final (interval închis). - Dacă nu se poate aloca fișierul (spațiu contiguu insuficient), tipăriți:
unde
fd: (0, 0)\nfdeste descriptorul fișierului respectiv.
- Citiți
- Dacă e
GET(cod2):- Citiți descriptorul fișierului.
- Tipăriți:
unde
(%d, %d)\n%d, %deste intervalul (start, end) în care se găsește fișierul, sau(0, 0)dacă nu există.
- Dacă e
DELETE(cod3):- Citiți descriptorul fișierului.
- Ștergeți fișierul (todos blocurile devin 0).
- Tipăriți întreaga stare curentă a memoriei, sub forma unei liste de descriptor per bloc, separată prin virgule și spațiu:
unde
d0, d1, d2, …, dM\nM= numărul total de blocuri – 1.
- Dacă e
DEFRAGMENTATION(cod4):- Reordonați blocurile astfel încât toate blocurile ocupate să fie lipite de la stânga la dreapta, păstrând ordinea fișierelor.
- Tipăriți starea curentă a memoriei (același format ca la DELETE).
- Prima linie:
-
Intervalele de blocuri și conversia dimensiunii
- Un fișier de
SkB necesităceil(S kB ÷ 8 kB) = ceil(S ÷ 8)blocuri în simulare (deoarece fiecare bloc stochează 8 kB). - În exemplu, s-a redus 8 kB → 8 B pentru a putea demonstra ușor.
- Un fișier de
-
Structura memoriei
- Dispozitivul este privit ca o matrice de dimensiune 8 MB × 8 MB → număr total de blocuri (
(8 MB / 8 kB) × (8 MB / 8 kB) = 1024 × 1024blocuri). - În demonstrație, 8 MB × 8 MB și bloc de 8 kB s-au redus la 8 B.
- Fiecare fișier este alocat pe linii succesive. O zonă contiguă de blocuri este definită pe aceeași linie/linii adiacente – practic, se caută primul “spațiu dreptunghiular” (o secvență de blocuri pe linii consecutive) suficient de mare.
- Dacă fișierul nu încape (contiguu pe linii), intervalul returnat este
((0, 0), (0, 0)).
- Dispozitivul este privit ca o matrice de dimensiune 8 MB × 8 MB → număr total de blocuri (
-
Codificarea operațiilor
1→ ADD2→ GET3→ DELETE4→ DEFRAGMENTATION
-
Formatul inputului
- Prima linie:
O= numărul de operații. - Pentru fiecare dintre cele
Ooperații:- Citiți codul de operație (1..5).
- Dacă e
ADD(cod1):- Citiți
N= numărul de fișiere care urmează să fie adăugate. - Pentru fiecare dintre cele
Nfișiere, două linii:- Descriptor (întreg ∈ [1..255]).
- Dimensiune în kB (întreg).
- Pentru fiecare fișier se tipărește:
unde primul
%d: ((%d, %d), (%%d, %d))\n%d= descriptor, apoi coordonatele colțului stânga-sus(startX, startY)și colțului dreapta-jos(endX, endY)(interval închis). - Dacă nu încape, tipăriți:
fd: ((0, 0), (0, 0))\n
- Citiți
- Dacă e
GET(cod2):- Citiți descriptor.
- Tipăriți:
cu coordonatele unde este stocat fișierul, sau
((%d, %d), (%d, %d))\n((0, 0), (0, 0))dacă nu există.
- Dacă e
DELETE(cod3):- Citiți descriptor.
- Ștergeți fișierul (toate blocurile cu acel descriptor → 0).
- Tipăriți întreaga stare a memoriei, sub forma unei matrice de
Rlinii ×Ccoloane (undeR = C = 1024în versiunea reală; în demonstrație, o dimensiune mai mică). Fiecare linie este afișată ca:unde fiecared0, d1, …, dC−1\ndieste descriptorul sau0.
- Dacă e
DEFRAGMENTATION(cod4):- Reordonați fișierele astfel încât toate blocurile ocupate să fie lipite “în sus și la stânga” (golurile mutându-se în dreapta-jos). Păstrați ordinea de alocare a fișierelor.
- Tipăriți memoria reordonată (tolată similar cu DELETE).
- Prima linie:
Codul este scris în limbaj de asamblare x86 (fișierele .s). Vă recomandăm să folosiți NASM (Netwide Assembler) și ld (linker-ul GNU) pentru a genera un executabil pe Linux (sau WSL) pe arhitectură elf32. Urmați pașii:
- Compilare task
gcc -m32 file_name.s -o file_name -no-pie -z noexecstack ./file_name < input.txt > output.txt Rulare cu fișier de input
În loc să introduceți manual operațiile, creați un fișier input.txt și scrieți acolo toate liniile de input conform formatului cerut, asemenea exemplului din directory. Rezultatul poate fi redirectionat catre un al fisier de output.txt