Generiranje kode
Zbiranje programa zaključimo z generiranjem kode. Pri tem lahko zapišemo surov program (pomnilniška slika za stroj SIC/XE) ali objektno kodo v formatu .obj
, ki jo v pomnilnik naloži nalagalnik.
Surova koda
Razredu Code
dodajte metodo
byte[] emitCode()
ki vrne surovo kodo za cel program. To kodo lahko neposredno prepišemo v pomnilnik stroja SIC/XE in začnemo izvajati. Kot običajno se metoda sprehodi po sintaktičnem drevesu in stakne bajte posameznih ukazov. Te generiramo z metodo emitCode
v podrazredih Node
. Pri tem:
- vsak format obravnavamo posebej;
- (navadne) direktive ne generirajo nič;
- pomnilniške direktive naj generirajo ustrezne podake oz. ničle.
Namesto, da Node.emitCode
vrača tabele bajtov, ji lahko kot argument date referenco na vnaprej rezervirano tabelo, v kateri vsak Node
nastavi bajte na ustrezni lokaciji. Pri delu z zaporedji bajtov si lahko pomagate tudi z razredoma ByteBuffer
ali ByteArrayOutputStream
.
Objektna koda
Razredu Code
dodajte metodo
String emitText()
ki vrne vsebino datoteke .obj
. Svoj zbirnik dopolnite, da za podani program ustvari datoteko .obj
. Dodajte tudi zapisa H
in E
. Pazite, da zapisi T
niso predlogi (do 60 znakov). Dejansko generiranje kode implementirajte v metodi emitText
v podrazredih Node
.
Za večino ukazov je dovolj, da pretvorite surovo kodo, ki jo vrne Node.emitCode
, v šestnajstiški zapis. Pazite predvsem na pomnilniške direktive:
- direktivi
BYTE
inWORD
generirata šestnajstiški zapis podatkov. - direktivi
RESB
inRESW
ne generirata ničesar, saj za nalaganje kode, ki sledi, poskrbi naslov v zapisuT
.
Kot prej lahko namesto stikanja podnizov metode Node.emitText
prejmejo objekt tipa StringBuilder
, kamor dodajajo svoje nize.
Dnevniška datoteka
Generiranje surove in objektne kode je precej težko razhroščevati. Lažje bo, če si napišete še metodo za izpis simbolov in njihovih lokacij ter metodo za izpis surove kode z lokacijami in ostalimi podatki. Za primer glejte dnevniško (.log
) datoteko simulatorja.
Napišite metodo
String dumpSymbols()
ki vrne spisek vseh definiranih simbolov. Za primer glej razdelek Symbols
v dnevniški datoteki.
Napišite metodo
String dumpCode()
ki vrne generirano kodo po naslovih in pripadajoče ukaze. Za primer glej razdelek Code
v dnevniški datoteki. Namigi:
- izpis naslova je enostaven;
- za izpis generirane kode uporabite
Node.emitCode
; - izpis ukaza in operandov lahko naredite po že dani predlogi (glej
Node.toString
), pri čemer je treba le povoziti metodeMnemonic.operandToString
v izpeljanih razredih.
Dopolnite glavni program, da ob zbiranju zapiše tudi log datoteko.