Informatika szigorlat 16-os tétel: Az assembly nyelvek tulajdonságai és fordítása Az assembly nyelv tulajdonképpen a gépi kód szimbolikus megfelelője, azért jött létre, hogy könnyebben lehessen programozni gépi kódi szinten, tehát az assembly alacsony szintű programozási nyelv, mellyel közvetlenül a CPU-t programozzuk. Manapság leginkább magasszintű nyelveken megírt programokhoz kapcsolnak assemblyben megírt részeket. Az assembly nyelv erősen gépfüggő. Az előző a tulajdonságából az is adódik, hogy könnyebben fordítható a magasszintű nyelvekhez képest. Masm: a Microsoft által írt makróassembler Intel processzorokhoz, DOS/Windows platformra Tasm: A Borland által írt assembler Intel processzorokhoz DOS/Windows platformra Nasm, as: ezek Linux alatti assemblerek Fordítása (vázlat):
Az assembly nyelv tulajdonságai: Az assembly nyelv sor-orientált nyelv, tehát minden sorba pontosan egy utasítás kerül. Egy sor mezőkből áll a következőképpen:
Egy sorban nem szükséges, hogy minden mező szerepeljen, értelemszerű en elmaradhatnak részek. Az utasítások: direktívák és mnemonic-ok lehetnek. A direktíva az assemblernek ad utasításokat (ilyen pl.: end, segment, db, stb.), a mnemonic-ok pedig a processzornak(pl.: MOV, JMP, CALL, NOP, stb.) Minden címke egy memóriacímet reprezentál. Operandus szám – az utasítástól függően – lehet 0,1,2,stb. Például: NOP – 0 operandus PUSH – 1 operandus MOV – 2 operandus A kommentet ; jel vezeti be, és a sor végéig tart.
Egy assembly nyelvű program három fő szegmensből épül fel: Adatszegmens (Data segment, DS) Veremszegmens (Stack segment, SS) Kódszegmens (Code segment, CS) Regiszterek és flag-ek: A regiszterek a processzor beépített változói. Vannak általános célú regiszterek, pl.: AX, BX, és vannak nem általános célúak, pl.: SP (Stack Pointer, veremmutató), IP(Instruction Pointer, utasításszámláló), stb. Ez utóbbiakat szegmens regisztereknek nevezzük. Felépítésük: AH+AL=AX. AX=EAX/2. Tehát az AH és AL 8-bitesek, az AX 16 bites, az EAX 32 bites. A flag-ek A flagek is egyfajta regiszterek, amelyek az elvégzett mű veletek eredményéről adnak információt, például CF:Carry Flag, egy aritmetikai mű veletnél adja meg, hogy volt-e átvitel vagy ZF:Zero Flag, akkor lesz 1, ha az eredmény 0 volt (ezt általában összehasonlításkor használjuk. További flag-ek: Trap Flag, Interrupt Enable Flag, Sign Flag, stb. A flagregiszterek 16 bitesek. Makrók A makróknak az assembly nyelvben az a szerepe, hogy az assembly nyelvű program hosszát rövidítsék, átláthatóbbá tegyék és ezzel a programozó munkáját megkönnyítsék. Makrónév macro … (Makrónév) endm szintaxissal rendelkezik.
paraméterlista
Magát a makrót minden meghívásánál kifejti az assembler, ezért a címkéket lokálissá (Local) kell tenni, különben többször definiáltnak veszi az assembler. Kifejtéskor a formális paraméterek helyére a valódi paramétereket helyettesíti. Építőelemek: - reserved words - konstansok - procedure: pnév PROC ... ret pnév ENDP -segment: snév segment típus ... snév ends
, ahol a típus lehet: - {readonly} - {align} (milyen címhatárra kerüljön: byte, word, para ) - {combine} (public, common) - {use} hány bites kódot fordítson (16,32) pl.: CODE SEGMENT PARA PUBLIC 'CODE' Assume cs segnév :ez csak infót ad az assemblert a szegmensregiszterek értéről, de nem állítja be azokat, ezt a programozó külön kell megtennie. -változók: címke típus érték pl.: alma SW ?, korte db 10 dup(?) Modulok: PUBLIC <szimb.lista>: külső modul is hozzáférhet az adott szimbólumhoz EXTERN
: az adott szimbólumot valamely másik modulban keressük. Címek: - short 1 byte - near 2 byte - far 4 byte Az assembly nyelvű programok fordítása 1-menetes assembler: A forrásnyelvű program egyszeri „végigolvasasával” tudja előállítani a tárgynyelvű programot, ill. hibákat és listákat. 2-menetes assembler: A forrásnyelvű programot kétszer „olvassa” végig, mire előállítja a tárgynyelvű programot, illetve a hibákat, listákat. A 2-menetes assemblerekre azért van szükség, hogy könnyebben kezelje mind predefinit, mind a postdefinit hivatkozásokat. Az 1-menetes assemblerek láncolt lista adatszerkezetekkel oldja meg a felmerülő problémákat. Léteznek ennél több menetes assemblerek is, de fölöslegesen, hiszen 2-menetes assemblerrel is fordíthatóak az assembly nyelvű programok. Ezek ezért ritkák is. Kicsit formálisabban: Assembler(ass.nyelvű prg.)(tárgy ny. prg., hibák listák) mindkét esetben. CLC: elhelyezés számláló, ami azt mutatja meg, hogy hova kerüljön a következő lefordított utasítás. A 2-menetes assemblerek az első menetben előállítják a szimbólumtáblát illetve esetleges hibaleírásokat, és a második menetben állítják elő a tárgykódot és a felmerülő hibák listáját. Általában az assemblerek a következő részekből épülnek fel: 1 Input-handler (assembly nyelvű program)(assembly nyelvű sor) 2 Assembler*(ass. nyelvű programsor)(tárgykód, hibák) 3 Code-handler (tárgykód) (tárgyprogram)
4
List-handler(assembly nyelvű program,hibák) (hibák,listák)
Szokás az input- és list-handlert egybefogni, és source-handlerként alkalmazni. Assembláláskor ezek nem egymás után futnak, hanem az, amelyikre éppen szüksége van az assemblernek. 2-menetes assembler 1.menet( forrásprogram sorai)(szimbólumtábla, hibák) Tehát az első menetben felépíti a szimbólumtáblát. Értékadás esetén a szimbólumok értékét meghatározza. 1. Mnemonic esetén mnemonic tábla segítségével, hossz és paraméterek meghatározása. A táblában a leggyakoribb utasítások vannak elől. Mnemonic: fix táblázat van az assemblerben:
Direktíva táblázat:
A címkék vizsgálata foglalja magába a szimbólumtábla építését. Ide a címke nem
kerül be, csak a <pointer,hossz> páros:
Lehetséges hibák: formátum hiba, többször definiált címkék. 2.menet(forrásprogram sorai, szimbólumtábla)(gépi kód, hibák) Itt történik a kód generálás. Itt lehet észrevenni az érték nélkül maradt címke hibát. 1-menetes assembler Itt is van utasítás, direktíva, szimbólumtábla. Trükk: listába fű zzük azokat a helyeket, ahol az ismeretlen szimbólumra hivatkozunk, majd amikor a szimbólum értéket kap, akkor töltjük ki visszamenőleg. Ekkor így néz ki a szimbólumtábla:
A tárgynyelvű (obj) programok egységes felépítésű ek: rekordokból állnak, a következőképpen:
Blokk típus értékek: - modul kezdete (név) - szegmensnevek - szegmens definíciós blokk (ahányat felsorolunk, annyi szegmens lesz) - kód illetve adat - címmódosítási lista - modul záró blokk Szimbólumtábla Szerkesztés
A tárgynyelvű program még nem futtatható. Ahhoz, hogy végrehajtható állományt készíthessünk belőle még össze kell szerkeszteni (linkelni).A linker nem feltétlenül egy tárgynyelvű programból állítja elő a futtatható programot, hanem adott esetben többől. A linker az adatszegmenseket és kódszegmenseket összeszerkeszti, a külső hivatkozásokat feloldja. Az assemblerhez hasonlóan ez is egy szimbólumtáblát épít fel, melyet szoktak Gtáblának nevezni (a G a globálisra utal):
Feladata: public nevek kigy jtése és értékük feljegyzése, minden extern névre meg kell találni a public párját, ahonnan az értéke kinyerhet .
A linker 2-menetes, első menetben előállítja a szimbólumtáblát (G táblát), a másodikban pedig a kódot. A 2. menetben: exe header elkészítése, a kód, adat szegmensek összeválogatása és összemásolása, címmódosító blokk által előírt módosítások végrehajtása ( hivatkozási címek program relatívvá alakítása: szegmens csoportok, és szegmenscsoportokon belüli offset). Megj.: vannak olyan szimbólumok, amelynek címét még a linker sem tudja megállapítani, például az adatszegmens kezdőcíme, melyek csak futtatható állomány relokálásánál derül ki. Az exe formátuma:
Betöltése: 1. Header olvasása 2. Betöltési kezdőcím 3. PSP (program szegmens prefix) meghatározása 4. load modul 5. relokációs tábla: memóriaterület lefoglalása 6. relokációk végrehajtása (szegmens hivatkozások kijavítása) 7. Indítás: a, SS,SP <<< header + betöltési kezdőcím b, ES,DS <<< PSP c, CS,IP <<< header (relokáció)
Makróassembler 1. Makrók
2. Táblázatok
A célkörnyezeteket makrókkal definiáljuk: DB,DW,... Táblázatot használunk, ehhez a táblázatgenerátor készíti el a makróból a táblázatot, ezután a makróassembler készíti el a különböz kódokat.
Cross-assembler: ahol a tárgykörnyezet nem egyezik meg a célkörnyezettel.