2014. június 3., kedd

Kitérő: mi a programnyelv és hogyan fut a program a számítógépen?

Most egy gyors, felületes leírást szeretnék írni, hogy mi is ez az egész programozásdi.



A számítógép csak gépi kódú progit tud futtatni. Úgy mondanám, hogy adsz neki egy számsorozatot, aztán azt mondod a procinak, hogy „na most értelmezd”. A számoknak van értelmük, mondjuk a 123 azt jelenti, hogy a köv. két számot add össze és tedd az „A” regiszterbe. A proci csak pár regisztert tud kezelni (ezt a programnyelvekben változónak nevezhetjük) A régi commodore 16-om 3 regisztert tudott kezelni (ezeknek a fantázianeve A X és Y volt). Ha több változót akartál használni egy algoritmusban, akkor macera volt.
Mondjuk ha össze akarod adni 3+4, et, akkor ez a számsor kell: 123,3,4 de ha most másik 2 számot akarsz összeadni, akkor előbb az eredményt tartalmazó regiszter tartalmát (ami most 7) ki kellett mentened a memóriába (ez egy memóriaművelet). Mondjuk a 88-as kódú parancs az, hogy „rakd ki a következő címre az A regiszter tartalmát”
Nézzük a köv. számsort:

123,3,4,88,77777,123,5,6,88,77778

Ez azt csinálja, hogy a memóriába a 77777-es címre 7-et rak, a 77778-asra 11-et (szólj, ha nem érted, miért!)
Az tiszta gépi kód: csak számok.
Nyilván senki sem szereti a parancskódokat memorizálni.
Ezért először csináltak egy ZZZ nevű progit (ilyen macerás módszerrel, számok memóriába írásával), ami rövid szöveges fájlokat alakít át gépi kóddá, például beolvassa ezt:
ADD 3,4
CPA 77777
ADD 5,6
CPA 77778
...és átalakítja a már ismert 123,3,4,88,77777,123,5,6,88,77778 számsorrá, amit valahol a memóriában elhelyez.

A fenti ADD, CPA stb (ezek az elnevezések rövidek voltak, valaki kitalálta, hogy így jó lesz) utasítások sora az első „assembly” nyelven összerakott programok voltak. Ez nem nevezhető magasabb szintűnek, mint a gépi kód, mert egy az egyben gépi kódú utasításokat eredményez, a ZZZ progi pedig az ASSEMBLER.
Ez még mindig nyilván macerás, viszont eszméletlen gyors. Egy modern proci 3-4 gépi kódú utasítást végrehajt egy órajel alatt, 3GHz-es proci esetén ez akár 12milliárd utasítás 1 mp alatt! (persze árnyalja a dolgot a memóriaműveletek szükségessége, stb, de mindenre most nem térhetek ki)

Észrevették, hogy bizonyos kódrészleteket sokszor használnak, például a regiszterek elmentését és visszatöltését a memóriába. Ezért fejlesztettek az ASSEMBLERen, hogy látszólag tetszőleges változóneveket fogadjon el, mondjuk a feldolgozható fájl ilyen lett:

ALMA:77777
KÖRTE:77778
ADD 3,4
CPA ALMA
ADD 5,6
CPA KÖRTE

Aztán továbbfejlesztették, hogy kifejezéseket is át tudjon alakítani, mondjuk ezt:
SZILVA=ALMA+KÖRTE

Azt hiszem már érted, hogy lett egyre magasabb szintű a programnyelv, ezeket már nem is ASSEMBLERnek hívták, hanem FORTRAN-nak, vagy C nyelvnek, stb,stb.

A nyelvi elemeket tehát egy valamilyen gépi kódú struktúrára fordította le a fordítóprogi, amit ASSEMBLERBEN írtak meg. Aztán persze írtak C nyelven is fordítót, miért is ne? Például lehet C nyelven írni egy jobb C nyelvű fordítót, operációs rendszert, stb.

A munka menete tehát ez:
0: elindítod az operációs rendszer programot (a gép elindítja magától), amivel tudsz alapvető parancsokat kiadni, programokat elindítani (szólni a procinak, hogy most az x. címtől kezdve írja felül a memóriát a lemezen található x. szektor tartalmával, majd az x. címtől kezdve értelmezze a számokat (bájtokat) a memóriában)
1: Az oprendszer alapparancsainak segítségével betöltesz a lemezről egy szövegszerkesztőt, és elindítod.
2. Írsz egy szövegfájlt egy szövegszerkesztő programmal (amit előtte valaki elkészített), elmented Z néven.
3. Elindítod a fordítóprogramot (ASSEMBLER.EXE, C.EXE, azt, amilyen nyelvben írtad a szövegfájlt), és megadod neki, hogy fordítsa le a Z fájlt és az eredményt tegye bele a Z.EXE fájlba. (Ezt nevezik BUILD-nek). Ergo bármilyen nyelven gyárthatsz exe-t, ha van olyan fordítód.

Mint látod, megvan az EXE fájl, ami már nagyrészt csak a gépi kódú, a processzor számára értelmezhető számokat tartalmazza.
Az oprendszer tudja, hogy ha EXE fájlt nyitsz meg, az futtatható, vagyis a memóriába valahova bemásolja, majd azt mondja a procinak, hogy „na ettől a ponttól értelmezd”. Kész, fut a programod.

Más módszer is van: amikor nem készít a fordító gépi kódot, hanem csak értelmezi a szövegfájlt.
Ekkor nem is fordítóról beszélünk, hanem INTERPRETER-ről. Nem készül EXE fájl, az interpreter végig a memóriában marad, amíg a programod fut. Lényegében nem a programod fut, hanem az interpreter, csak épp azt teszi, amit a programodban a szövegfájlban megadtál.
Ennek az az előnye, hogy rögtön elindul, kimarad a BUILD. Hátránya, hogy lassabb, mintha csak az EXE futna.
A leghíresebb interpreter a BASIC interpreter volt.
A Javascript is a böngészőkben ilyen volt, míg nem jött a Google. Manapság a JavaScriptet „on the fly” lefordítja a böngészőben lévő builder gépi kódra, elindítja, majd ha már nem kell, akkor kidobja – vagyis készül exe-szerű cucc, csak nem írja senki a lemezre.

Linux rendszerekben nincs exe kiterjesztése (feltétlenül) a futtatható állományoknak.
A különböző oprendszerek és processzorok megkavarják a helyzetet.
Készítettek ezért virtuális gépeket mindenféle oprendszerre és processzorfajtákra, amik ugyanúgy próbálnak működni, mindenhol. Ezek amolyan félig interpretált, félig „natív” futású dolgok lesznek, ha ezekre írsz progit. A leghíresebb ilyen rendszer a JAVA nyelv és annak a JAVA virtualmachine-je. (mint láthatod, a JAVA az tök más, mint a Javascript)

Ehhez hasonló van Androidon is. (Ezért pereli most a Google-t az Oracle, a Java jogtulajdonosa. Vérszívók) . Androidon az APK a futtatható fájlokat tartalmazza, plusz az egyéb fájlokat, amiket a progid használ. Az Android rendszere ad lehetőségeket a programok számára fájlok, hálózat, stb elérésére, és ha nincs benne biztonsági rés, akkor a programok egymásra nem hatva, elkülönülten futnak. Az APK azért kell, hogy az Android tudhassa, hogy a benne lévő fájlok egy alkalmazáshoz tartoznak, vagyis ezekhez a progi korlátozás nélkül is hozzáférhet (meg ilyesmik).

Nincsenek megjegyzések:

Megjegyzés küldése