Sistemski softver/Projekat

Izvor: SI Wiki
Pređi na navigaciju Pređi na pretragu

Projekat na predmetu Sistemski softver je obavezan i sastoji se od 3 programa koji čine skup alata za razvoj softvera na apstraktnom računarskom sistemu. Ovaj vodič teži da bude nezavisan od postavke, koja se neznatno menja iz godine u godinu.

Podela po celinama

Zbog svog velikog obima, preporučuje se detaljna razrada zahteva na lako razumljive celine i korake. Preporučuje se sledeći redosled zadataka:

  1. Tabelarno predstavljanje mašinskih instrukcija i adresiranja u sklopu simboličkog mašinskog jezika asemblera i samog mašinskog koda. Pre nego što se krene sa implementacijom leksera i parsera neophodno je detaljno pregledati tražene zahteve u jeziku.
  2. Izrada modela simboličkog mašinskog jezika u softveru. Ovde se može primeniti objektno orijentisani pristup modelovanju, ili strukturni pristup nalik izlaznom formatu.
  3. Razvoj leksera i parsera koristeći generatore flex i bison ili pisanjem svog leksera i parsera.
  4. Izrada modela izlaznih podataka asemblera. Ovo uključuje sekcije, relokacije, simbole i sve što nije bilo pokriveno modelovanjem jezika.
  5. Implementacija samog asembliranja. Prolazi se kroz izlaz parsera i popunjava izlazni model.
  6. Opciono tekstualno/grafičko predstavljanje izlaznih podataka nalik readelf i objdump olakšava debagovanje.
  7. Testiranje asemblera.
  8. Modelovanje i implementacija izlaznog binarnog formata asemblera
  9. Model ulaznih podataka linkera. Mogu se koristiti i strukture iz asemblera, ali nije preporučljivo jer su neophodni podaci za rad linkera i asemblera znatno različiti - sve postojeće enkapsulacije i interfejsi verovatno nisu dovoljno univerzalni ili su ograničavajući.
  10. Implementacija linkera
  11. Implementacija ispisa radne memorije u tekstualni fajl, kao i ispisa u prethodno osmišljeni objektni format, za šta kod ne bi trebalo da se znatno razlikuje.
  12. Testiranje linkera.
  13. Modelovanje memorije u emulatoru. Učitavanje memorije iz fajla.
  14. Modelovanje procesora, registara, obrade prekida.
  15. Implementacija emuliranja instrukcija. Sa naglaskom na pažljivo pisanje koda i razumevanje postavke.
  16. Implementacija periferije terminal. Postavka preporučuje termios biblioteku.
  17. Implementacija periferije tajmer.
  18. Testiranje emulatora.

Ne treba zaboraviti pisanje make skripte za pravljenje projekta pri samom početku izrade, zato što se znatno ubrzava vreme prevođenja. Prezentacija koja objašnjava kako koristiti GNU make se nalazi u odeljku Vežbe 2.

Subjektivno gledano, delovi projekta koji najviše oduzimaju vremena su: leksička analiza (vreme učenja alata ili pisanje svojih), format izlaznog fajla (neophodno je naći balans između lakog generisanja i lakog čitanja) i testiranje emulatora (male greške u ponašanju instrukcija).

Asembler

Tabelarno predstavljanje mašinskih instrukcija i adresiranja

Postavka projekta sadrži mnogo informacija koje nisu naročito kvalitetno organizovane i predstavljene. Tabelarna reorganizacija projekta pomaže pri izradi i zato se preporučuje. Dat je primer za projekat iz 2022. godine. Primetiti da je u ovoj postavci podatak u instrukciji big endian, a podatak u memoriji little endian. Podebljana slova označavaju polja koja se zamenjuju pri generisanju mašinskog koda. Značenja su: D - odredišni registar S - izvorni registar.

Instrukcije u asembli jeziku
Instrukcija Dužina u bajtovima InstrDescr RegsDescr AddrMode DataHigh DataLow
0 1 2 3 4
HALT 1 00
IRET 1 20
RET 1 40
INT 2 10 DF
PUSH 3 B0 6S 12
POP 3 A0 D6 42
NOT 2 80 D0
XCHG 2 60 DS
ADD 2 70 DS
SUB 2 71 DS
MUL 2 72 DS
DIV 2 73 DS
CMP 2 74 DS
AND 2 81 DS
OR 2 82 DS
XOR 2 83 DS
TEST 2 84 DS
SHL 2 90 DS
SHR 2 91 DS
CALL 3/5 30 FS Adresiranje za skok
JMP 3/5 50 FS Adresiranje za skok
JEQ 3/5 51 FS Adresiranje za skok
JNE 3/5 52 FS Adresiranje za skok
JGT 3/5 53 FS Adresiranje za skok
LDR 3/5 A0 DS Adresiranje za podatke
STR 3/5 B0 DS Adresiranje za podatke

U tabelama adresiranja, polja su: L - deo literala S - deo vrednosti simbola, D - odredišni registar, R - izvorni registar.

Adresiranje za skok
Notacija Adresiranje 1 2 3 4
<literal> Neposredno F0 00 LL LL
<symbol> Neposredno F0 00 SS SS
%<symbol> PC relativno F7 05 SS SS
*<literal> Mem. direktno F0 04 LL LL
*<symbol> Mem. direktno F0 04 SS SS
*<reg> Reg. direktno FR 01
*[<reg>] Reg. indirektno FR 02
*[<reg>+<lit>] Reg. ind. sa pomerajem FR 03 LL LL
*[<reg>+<sym>] Reg. ind. sa pomerajem FR 03 SS SS
Adresiranje za podatke
Notacija Adresiranje 1 2 3 4
$<literal> Neposredno D0 00 LL LL
$<symbol> Neposredno D0 00 SS SS
%<symbol> PC relativno D7 03 SS SS
<literal> Mem. direktno D0 04 LL LL
<symbol> Mem. direktno D0 04 SS SS
<reg> Reg. direktno DR 01
[<reg>] Reg. indirektno DR 02
[<reg>+<lit>] Reg. ind. sa pomerajem DR 03 LL LL
[<reg>+<sym>] Reg. ind. sa pomerajem DR 03 SS SS

Ovakve tabele odlično predstavljaju šta je dati izlaz u mašinskom kodu za dati ulaz u jeziku. Preporuka je koristiti ih pri modeliranju ulaznih podataka i leksičke analize.

Modelovanje jezika

Primer modela jezika

Preporuka je upoznati se sa alatima flex i bison pre pisanja bilo kog koda i daljeg čitanja vodiča. Korisno je naći tutorijal:

Primena ovih alata za asembler nije trivijalna, i bolje je izdvojiti vreme na pisanju prostijih primera pre početka pisanja asemblera, npr. učitavanje memorije iz hex izlaza linkera u emulator.

Parser uklapa ulazni tekst u prethodno napisana pravila (više o tome na prevodiocima). Pravila izgledaju slično sintaksnim notacijama kao na P1. Pravila se uklapaju od manjih do većih. Kako se ulaz uklopi u pravilo, izvrši se određena radnja. Radnja parsera u našem slučaju je konstrukcija struktura/objekata koje predstavljaju delove jezika, i eventualno spajanje tih jezičkih elemenata u listu kroz koju prolazi sam asembler. Na slici desno je dat primer modela.

Parser popunjava listu elemenata jezika (namerno se ne zovu linije jer je moguće imati više njih u jednoj liniji). Iz elemenata se izvode direktive i instrukcije. Svaka specijalizacija direktive sadrži neki njoj bitan podatak (naziv simbola, literali, izrazi i slično) koji će parser proslediti iz leksema (jezičkih jedinica, npr. literal, identifikator) pri konstrukciji. Slično važi i za instrukcije, gde su namerno odvojena adresiranja kao objekti koje parser kreira pre uklapanja u samu instrukciju, zato što parser uklapa adresiranja pre nego što uklopi instrukciju sa adresiranjem. Kasnije, pri nastanku (uklapanju) instrukcije, ona postaje vlasnik objekta adresiranja. Asembler će, pomoću ovakvog modela, u svojim prolazima (ili prolazu) imati dostupne sve detalje iz ulaznog fajla. Korisno je pri konstrukciji pamtiti i broj linije na kom se element nalazi, radi lepšeg izveštavanja grešaka.

Linker

Emulator

Testovi