ja ja TIE448 Kääntäjätekniikka, syksy 2009 Antti-Juhani Kaijanaho TIETOTEKNIIKAN LAITOS 2. marraskuuta 2009
Sisällys ja
Sisällys ja
Seuraava deadline ja Vaihe D tiistai 10.11. klo 10 välikielen generointi Vaihe E tiistai 24.11. klo 10 koodigenerointi (ilman rekisteriallokaatiota)
Kääntäjän rakenne ja lähdeohjelma SELAAJA sanasjono JÄSENTÄJÄ rakennepuu VÄLIKOODIN GENEROIJA välikoodi KOHDEKOODIN GENEROIJA kohdeohjelma TARKASTAJA SOKERINPILKKOJA OPTIMOIJA OPTIMOIJA
Sisällys ja
16 yleiskäyttöistä 64-bittistä rekisteriä ja bitit 63 0 bitit 31 0 bitit 15 0 bitit 15 8 bitit 7 0 0 RAX EAX AX AH AL 1 RBX EBX BX BH BL 2 RCX ECX CX CH CL 3 RDX EDX DX DH DL 4 RDI EDI DI DIL 5 RSI ESI SI SIL 6 RBP EBP BP BPL 7 RSP ESP SP SPL 8 R8 R8D R8W R8B 9 R9 R9D R9W R9B 10 R10 R10D R10W R10B 11 R11 R11D R11W R11B 12 R12 R12D R12W R12B 13 R13 R13D R13W R13B 14 R14 R14D R14W R14B 15 R15 R15D R15W R15B
RFLAGS tilabittejä ja 0 CF carry yhteenlaskun muistibitti 1 2 PB parity pariteetti 3 4 AF aux carry apumuistibitti 5 6 ZF zero oliko tulos nolla? 7 SF sign oliko tulos negatiivinen? 8 9 10 DF direction silmukkakäskyjen suunta 11 OF overflow kokonaislukuylivuoto 12 63 Tilabitit vaikuttavat ehdollisten käskyjen (esim. hypyt) toimintaan.
CF RFLAGS ja Kokonaislukujen yhteen- tai vähennyslasku asettaa tämän: CF=1, jos yhteenlaskusta jää muistibitti tai vähennyslasku tarvitsi lainabitin, ja CF=0 muuten. INC ja DEC eivät vaikuta CF:ään. Bitinsiirtokäskyt käyttävät CF:ää. AND, OR, XOR asettavat CF=0. STC asettaa CF=1 CLC asettaa CF=0 JC hyppää, jos CF=1 JNC hyppää, jos CF=0 Tarpeen lähinnä suurten (yli 64 bittiä) lukutyyppien käsittelyssä.
PF, AF, DF RFLAGS ja Tietyt operaatiot asettavat PF:n sen, mukaan onko tuloksessa parillinen (PF=1) vai pariton määrä (PF=0) bittejä. Ns. desimaaliaritmetiikka käyttää AF:ää. Tietyt ns. jononkäsittelykäskyt käyttävät DF:ää Eivät kiinnostavia kääntäjätekniikan kannalta.
ZF, SF, OF RFLAGS ja Laskutoimituksen tuloksen mukaan asetetaan: ZF=1, jos tulos oli nolla, ja ZF=0, jos tulos ei ollut nolla, sekä SF = tuloksen eniten merkitsevä bitti. Etumerkillisen laskutoimituksen tuloksen mukaan asetetaan lisäksi OF=1, jos tapahtui ylivuoto, ja OF=0 muuten.
Yleiskäyttöiset tietotyypit ja eri kokoisia bittijonoja... n = 8, 16, 32, 64 rajoitetusti myös n = 128... joita voi tulkita eri tavoin: bittijono etumerkitön kokonaisluku (aritmetiikka modulo 2 n ) etumerkillinen kokonaisluku (kahden komplementti) binäärikoodattu kymmenjärjestelmäluku (BCD) pakattu BCD BCD-tulkinnat eivät ole kääntäjätekniikan kannalta kiinnostavia. Lisäksi voidaan käsitellä näistä muodostettuja jonoja ( strings )
Operandit ja imm välitön operandi (arvo on osa käskyä) voi olla 8-, 16- tai 32-bittinen. 64-bittisen välittömän operandin voi antaa rekisteriin kopiointia varten. reg käskyssä nimetty rekisteri voi olla mikä vain yleiskäyttöinen rekisteri. mem käskyssä kuvataan muistiosoite, jossa oleva muistipaikka on operandina nasmissa osoitteen ilmaiseva lauseke laitetaan aina hakasulkeisiin, esim. [EBP-16].
Muistipaikkaan viittaaminen ja Osoite (enintään 32 bittiä) voidaan antaa käskyssä sellaisenaan. Osoite voidaan antaa siirtymänä (enintään 32 bittiä) käskyn osoitteesta. Osoite voidaan laskea kaavalla r 1 + s r 2 + d, missä r 1 ja r 2 ovat yleiskäyttöisiä rekistereitä, d = 1, 2, 4, 8 ja d on käskyssä annettu etumerkillinen kokonaisluku (enintään 32 bittiä). (Tämä on ns. modr/m-osoitus.) Tietyt käskyt käyttävät implisiittisesti RSP- tai RBP-rekisterin arvoa osoitteena.
Käskyjen rakenne ja Käsky koostuu operaatiosta sekä enintään kahdesta operandista. Ensimmäinen operandi on se, minne tulos talletetaan. Jos käsky tarvitsee kaksi lähdettä (esim. yhteenlasku), ensimmäinen operandi on myös ensimmäinen lähdeoperandi. Käskyä voi edeltää etuliite.
Tiedonsiirtokäskyt (MOV, MOVSX, MOVZX ja MOV siirtää dataa rekisterien taikka rekisterin ja muistin välillä. siirto muistista muistiin on kielletty lähde voi olla myös välitön vakio MOV reg, imm on ainoa käsky, jolle voi antaa 64-bittisen vakion. lähteen ja kohteen tulee olla samankokoiset MOVSX ja MOVZX hakevat dataa muistista rekisteriin. Kohteen tulee olla lähdettä suurempi. MOVSX tekee etumerkkilaajennoksen. MOVZX tekee nollalaajennoksen.
Pinonkäsittely ja PUSH rand tarkoittaa samaa kuin SUB RSP, koko(rand) MOV rand, [RSP] POP rand tarkoittaa samaa kuin MOV rand, [RSP] ADD RSP, koko(rand) ENTER imm, 0 tarkoittaa samaa kuin PUSH RBP MOV RBP, RSP SUB ESP, imm1 LEAVE tarkoittaa samaa kuin MOV RSP, RBP POP RBP
Osoitearitmetiikka (LEA) ja LEA reg, mem laskee lähteenä olevan muistiosoitteen ja tallettaa ko. osoitteen rekisteriin. vrt. MOV reg, mem, joka tallettaa osoitteen tarkoittaman muistipaikan sisällön. Voidaan käyttää myös normaaliin aritmetiikkaan, esim. LEA RAX, [RBX+4*RCX+16] laskee hakasulkeissa olevan laskutoimituksen.
Kokonaislukujen yhteen- ja vähennyslasku ja ADD laskee yhteen ja SUB vähentää lähde ja kohde voivat olla muistipaikkoja, ei kuitenkaan yhtä aikaa lähde voi olla myös välitön vakio etumerkillinen ja etumerkitön samoilla käskyilla ADC, SBB kuten ADD ja SUB mutta ottavat huomioon CF-lipun asennon. Käytetään lähinnä isojen (>64bit) lukutyyppien laskentaan. NEG laskee ainoan operandinsa vastaluvun INC lisää ja DEC vähentää yhdellä
Kokonaislukujen kerto- ja jakolasku ja MUL laskee etumerkittömän kertolaskun n-bittisen laskun tulos on 2n-bittinen. 8-bittisessä laskennassa toinen operandeista on AL, tulos AX:ssä 16-bittisessä AX, tulos DX:AX:ssä 32-bittisessä EAX, tulos EDX:EAX:ssä 64-bittisessä RAX, tulos RDX:RAX:ssä IMUL laskee etumerkillisen kertolaskun myös kolmeoperandinen variantti (!) DIV laskee etumerkittömän jakolaskun, IDIV etumerkillisen jaettava 2n-bittinen, jakaja n-bittinen jaettava kuten tulos MUL-käskyssä (rdx:rax) DIV/IDIV-käskyä on aina syytä välttää jos mahdollista
Bittioperaatiot ja vertailu ja AND, OR, XOR, NOT tavanomaiset bitittäiset operaatiot CMP on kuin SUB paitsi ei tallenna tulosta mihinkään TEST on kuin AND paitsi ei tallenna tulosta mihinkään
Hypyt JMP on ehdoton hyppy kohde voi olla miten tahansa esitetty osoite Ehdollisissa hypyissä kohde esitetään aina siirtymänä nykyisestä käskystä. JO JNO JB, JC, JNAE JB, JNC, JAE JZ, JE JNZ, JNE JNA, JBE JNBE, JA JS JNS JP, JPE JNP, JPO JL, JNGE JGE, JNL JNG, JLE JNLE, JG OF=1 OF=0 CF=1 CF=0 ZF=1 ZF=0 CF=1 tai ZF=1 CF=0 ja ZF=0 SF=1 SF=0 PF=1 PF=0 SF =OF SF=OF ZF=1 tai SF =OF ZF=0 ja SF=OF ja
Aliohjelmakutsut CALL kohde tarkoittaa samaa kuin LEA RAX,.L1 PUSH RAX JUMP kohde L1: paitsi että se ei koske RAX-rekisteriin. RET imm tarkoittaa samaa kuin POP RAX POP BL... imm kpl... POP BL JUMP [RAX] paitsi että se ei koske RAX- eikä BL-rekistereihin. CALL ja RET ovat tehokkaampia kuin vastaavat käskyjonot, jos kutsut ja paluut ovat asianmukaisesti sisäkkäisiä. ja
SYSV ABI -kutsusekvenssi Paramerinvälitys: Kuusi ensimmäistä kokonaisluku- ja osoitinparametria välitetään rekistereissä RDI, RSI, RDX, RCX, R8, R9. Muut välitetään pinossa, pushaus vasemmalta oikealle -järjestyksessä. Rakenteisilla tyypeillä ja liukulukutyypeillä omat sääntönsä (ks. ABI) stdargs-funktioita kutsuttaessa AL:llä erityistehtävä (ks. ABI) Kaksi ensimmäistä kokonaisluku- ja osoitinpaluuarvoa palautetaan RAX:ssa ja RDX:ssä. Muista ks. ABI. Pinossa ensiksi mahdolliset pinoargumentit, sitten paluuosoite, sitten vanha RBP (dynaaminen linkki), sitten paikalliset muuttujat. RSP-8 on oltava 16:lla jaollinen kutsun tapahtuessa RBP, RBX ja R12 R15 ovat callee-save, eli funktion on palautettava niiden alkuperäiset arvot ennen paluutaan. ja
SYSV-sektiot ja Unixissa ohjelma jaetaan yleensä useaan sektioon:.text sisältää ohjelmakoodin.data sisältää alustetut globaalit muuttujat.bss sisältää nollaksi alustetut globaalit muuttujat.rodata sisältää alustettuja vakioita
Sisällys ja
Rekisteristö ja 256 yleiskäyttöistä 64-bittistä rekisteriä $0 $255. Osa loppupään rekistereistä on globaaleja. Osa alkupään rekistereistä on lokaaleja. Loput eivät ole käytössä. Jos tällaista rekisteriä käytetään, se ja sen alla olevat rekisterit muuttuvat lokaaleiksi. Lisäksi 32 erityisrekisteriä nimeltään ra rzz.
Käskyjen rakenne ja Käskyt ovat muotoa OP X, Y, Z. X on yleensä kohde, Y ja Z lähteitä. X, Y ja Z ovat rekistereitä. Z voi myös olla tavun kokoinen välitön vakio.
Tiedonsiirto ja LDx X, Y, Z lataa rekisteriin X muistiosoitteesta Y+Z löytyvän etumerkillisen tiedon. LDxU lataa rekisteriin X muistiosoitteesta Y+Z löytyvän etumerkittömän tiedon. LDHT X, Y, Z lataa rekisterin X ylimpään 32 bittiin osoitteesta Y+Z löytyvän tiedon ja nollaa X:n alimmat 32 bittiä. LDA X, Y, Z lataa rekisteriin X muistiosoitteen Y+Z. STx X, Y, Z tallettaa rekisterin X etumerkillisen sisällön muistiosoitteeseen Y+Z. STxU X, Y, Z tallettaa rekisterin X etumerkittömän sisällön muistiosoitteeseen Y+Z. STHT X, Y, Z tallettaa rekisterin X ylimmät 32 bitit muistiosoitteeseen Y+Z. STCO X, Y, Z tallettaa tavuvakion X osoitteen Y+Z tarkoittamaan 64-bittiseen muistipaikkaan. x=b,w,t,o sen mukaan onko tiedon koko 8, 16, 32, 64 bittiä.
Aritmetiikka ja ADD X, Y, Z suorittaa etumerkillisen laskutoimituksen X = Y + Z. SUB X, Y, Z suorittaa etumerkillisen laskutoimituksen X = Y Z. MUL X, Y, Z suorittaa etumerkillisen laskutoimituksen X = Y Z. DIV X, Y, Z suorittaa etumerkillisen laskutoimituksen X = Y/Z ja tallettaa jakojäännöksen erityisrekisteriin rr. ADDU, SUBU kuten ADD ja SUB, etumerkittömänä. MULU X, Y, Z suorittaa etumerkittömän laskutoimituksen rh : X = Y Z. DIVU X, Y, Z suorittaa etumerkittömän laskutoimituksen X = rd : Y/Z ja tallettaa jakojäännöksen erityisrekisteriin rr. Lisäksi naddu X, Y, Z suorittaa etumerkittömän laskutoimituksen X = n Y + Z, missä n = 2, 4, 8, 16. NEG(U) X, Y, Z laskee X = Y Z; Y:n on oltava vakio.
Vertailu ja bitittäiset ja CMP X, Y, Z tallettaa X:ään 1, jos Y < Z, 0, jos Y = Z, +1, jos Y > Z. AND, OR, XOR tavanomaiset ANDN, ORN ovat and-not ja or-not NAND, NOR, NXOR ovat not-and, not-or, not-xor
Hypyt ja JMP on ehdoton hyppy GO X, Y, Z on tavanomainen aliohjelmakutsu: X:ään tallennetaan paluuosoite ja Y + Z on kohdeosoite. BN X, L: jos X on negatiivinen, hyppää L:ään BZ X, L: jos X on nolla, hyppää L:ään BP X, L: jos X on positiivinen, hyppää L:ään BNN X, L: jos X ei ole negatiivinen, hyppää L:ään BNZ X, L: jos X ei ole nolla, hyppää L:ään BNP X, L: jos X ei ole positiivinen, hyppää L:ään
Aliohjelmakutsut rekisteri-ikkunan avulla ja PUSHJ $X, L: piilota rekisterit $0:sta $X:ään (jolloin rekisteri $(X+!) muuttuu rekisteriksi $0), tallenna paluuosoite rj:hin ja hyppää L:ään. PUSHGO $X, Y, Z: kuten PUSHJ, mutta hypätään Y+Z:aan POP X, Y, Z: poista käytöstä kaikki X:ää korkeammat paikalliset rekisterit palauta viimeisimmän PUSHJ/PUSHGO:n piilottamat rekisterit niin, että $0 $X muuttuvat piilotettuja rekistereitä seuraaviksi rekistereiksi.
Sisällys ja
Seuraava deadline ja Vaihe D tiistai 10.11. klo 10 välikielen generointi Vaihe E tiistai 24.11. klo 10 koodigenerointi (ilman rekisteriallokaatiota)