A gépi nyelv hogyan tud lefutni, és elindítani a processzort?
Berakom ide is, amit priviben válaszoltam:
Az interpreter és az assembler az két különböző típusú dolog. Az assembler az lényegében egy fordító, ami gépi kóddá alakítja az assembly kódot (erre még példa a C, C++ is). Gépi kóddá alapkítás során jön létre a futtatható fájlod, vagyis a program.
Egy interpreter az nem csinál végeredményben futtatható bináris fájlt, hanem a forráskód (pl. python kód) sorait szépen egymás után lefuttatja. Belül persze ez is gépi kódként kerül a processzorra, de itt a gépi kóddá alakulás a program futása közben történik. Ennek az az előnye, hogy bárhol, ahol az interpreter fut, bámilyen változtatás nélkül lehet futtatni. A hátránya, hogy lassabb, mert a gépi kóddá alakítás megörténik minden futásnál
+ Kiegészítés:
Az assembler az majdnem 1-1 megfeleltetésben van a gépi kóddal, csak sokkal olvashatóbb, mert nem 0-1 számokkal kell dolgozni, hanem szavakkal
A legegyszerűbb processzor alapvető működésének a leírása is elég bonyolult. Ez az oldal például egy alapvető funkciókat ellátó processzor felépítését írja le, ebből választ kappasz az össze kérdésedre:
A konkrét kérdéseidre a válasz:
" a processzor mért, és hogyan dolgozza ezeket föl?"
A processzor egy automata, ami ismétlődően (ezt egy órajel vezérli) beolvassa a memóriából az egyszerű utasításokat és ezeket az ALU részegysége végrehajtja. Az ALU egy alapvető logikai és aritmetikai műveleteket végrehajtó, logikai áramkörökből felépülő része a processzornak.
"mért indul el a feldolgozása bizonyos parancsokra, és másokéra mért nem"
Ennek az ALU-nak és az úgy nevezett utasításdekódernek a konkrét felépítése határozza meg, hogy egy processzor milyen "uatsításokat" képes végrehajtani. (Az ALU és a dekóder részleteit lásd a cikkben.)
"A gépi nyelv hogy tud lefutni"
A processzor a "program counter" által mutatott memóriacímről beolvassa a következő utasítást, amit aztán dekódol, illetve növeli a program counter értékét.
"A gépi nyelv hogy tud lefutni?"
A dekóder képes felbontani az utasításokat elemi műveletekre és ez alapján vezérelni az ALU-t.
"Két szám összeadása milyen parancsokkal működne?"
Ez a konkrét processzor típustól függ.
Nagyon egyszerűen leírva így működnek a dolgok:
1. Fordítóprogram (compiler)
Átadod a "magas" szintű programot/forráskódot neki (pl. C++), és az elemzi a kódot, aztán futtatható állományt készít (pl. exe fájl). Ez általában hexadecimális (16-os) számrendszerben lévő "gépi" kód, mert így kevesebb helyet foglal, de a végén ebből is bináris lesz (0-ák és 1-esek). Ez az adott processzor fajtájától, típusától függő egyedi kód (pl. Intel x86). Tehát az összes többi más fajta processzorra (pl. AMD, ARM) külön le kell futtatnod a fordítóprogramot ugyan arra a forráskódra.
Ez azért van, mert minden processzor máshogy készül (más az architektúrája), máshogy működik, máshogy kell megvalósítani rajta a feladatokat. Lent írok pár linket ehhez, hogy jobban megértsd.
2. Interpreter
Átadod a "magas" szintű programot/forráskódot neki (pl. Python), és az utasítás feldolgozása után végre is hajtja azonnal, nem pedig egy másik kódot generál, mint a fordítóprogram. Azaz ez már egy futó program, kap egy utasítást, és futás közben végre hajtja. Egy ilyen utasítás már a futó programon belül egy újabb hívás.
3. Fordítóprogram + Interpeter egyben (pl. Java Compiler)
Átadod a "magas" szintű programot/forráskódot neki (pl. Java), és köztes kódot (pl. Java esetén bytecode-ot) fordít belőle az 1-es lépéshez hasonlóan. Ezután ezt az elég jó állapotú köztes kódot átadja egy Interpreternek (Java esetén Java Virtual Machine), ami a 2-es lépéshez hasonlóan működik.
De hogy kapcsolódik ehhez az Assembly?
-
Az Assembly NEM gépi kód!!
Az Assembly fordítója (pl. NASM, MASM) az 1. pont szerint működik. A processzor fajtájához való Assembly kódban megírt forráskódot átfordítja "gépi" kódra. Azaz egy futtatható állományra. Pl. ha te linux-ra szeretnél egy 64 bit-es Intel processzorra fordítani, akkor a NASM-nak át kell adni ezeket a paramétereket, hogy a megfelelő gépi kódot/futtatható állományt fordítsa.
Mi az a futtatható állomány?
-
A futtatható állomány azt jelenti, hogy elindítod a programot, a számítógéptől kap processzor időt (amikor végrehajtódnak a parancsok) és RAM-ot (ahol a futáshoz szükséges adatot letárolod). Ezután az utasításai végrehajtódnak (a magas szintű programod pl. C++ minden parancsa itt már egy sokkal egyszerűbb művelet pl. összeadások, kivonások ilyesmi).
A számítógép ilyenkor már fut, tehát a processzor fut és a RAM-ban is be van töltve egy csomó operációs rendszer adat.
De miért akarnék Assembly-t használni, ha ott van pl. a Java, C++?
-
Általánosan az Assembly nyelvekben sokkal mélyebben tudsz programozni. Pl. közvetlenül tudod írni/olvasni a processzor memóriáját (regiszterek), nincs nagyon extra réteg már a gépi kód fölött. Ha értesz hozzá, sokkal gyorsabb és kevesebb erőforrást fogyasztó programot írhatsz.
Akár egy okos hűtő chipjére is. Ha itt belezavarodtál, akkor a "chip" annyit jelent, hogy microchip, azaz a bonyolultabban működő "microprocessor"-tól jóval egyszerűbb áramkör.
Ha ez részletesebben érdekel itt van pár anyag:
- https://www.youtube.com/watch?v=F2KcZGwntgg
- https://www.youtube.com/watch?v=QZwneRb-zqA
#14 vagyok:
"Tehát az összes többi más fajta processzorra (pl. AMD, ARM) külön le kell futtatnod a fordítóprogramot ugyan arra a forráskódra."
Ezt rosszul írtam, "Tehát az összes többi más fajta processzorra (pl. AMD, ARM) külön le kell futtatni a fordítóprogramot, egy ÚJRA ÍRT forráskódra."
"Általánosan az Assembly nyelvekben sokkal mélyebben tudsz programozni. Pl. közvetlenül tudod írni/olvasni a processzor memóriáját (regiszterek), nincs nagyon extra réteg már a gépi kód fölött. Ha értesz hozzá, sokkal gyorsabb és kevesebb erőforrást fogyasztó programot írhatsz."
Ez eszetlen nagy baromság már bocs. Ez kb. a 8 bites mikroprocikra volt igaz valamikor kb. 45-50 évvel ezelőtt. Égtelen szamárság és tévedés.
Nagyon röviden (leegyszerűsítve). A processzor úgy van megépítve, hogy erre képes legyen. Az utasítás végrehajtás úgy néz ki, hogy
1./ fogja a processzor a memóriából beolvassa a következő utasítást. Ez bekerül az ún. utasítás regiszterbe.
2./ Az utasítás regiszterből bekerül az ún. utasítás dekóderbe. Ez meghatározza, hogy az utasítás végrehajtásáházo melyik áramköröket kell "aktiválni" (és milyen sorrendben). Az utasítás itt ún. gépkódban érkezik (azért gépi kód, mert ezt képes értelmezni az utasítás dekóder). Pl. jön egy olyan utasíás, hogy másold be a B regiszter tartalmát az A regiszterbe. Ekkor a másoló áramkört aktiválja úgy, hogy kiválasztja, hogy az eredmény az A regiszterbe kerüljön és a B-ből másoljon.
Vagy egy másik utasítás másoljon egy adott címen lévő memóriából a B regiszterbe. Akkor ugyanaz, kiválasztja a megadott memória címet, ami adatot ott talál bemásolja B regiszterbe (megint a másoló áramkörrel van szükség). És minden egyes utasításnál megvannak a szükséges áramkörök amelyeket így aktiválnia kell. Vannak olyan utasítások amikhez több lépést is el kell végeznie, azt szépen majd az adott utasítás ármköre "lerendezi".
Aztán, hogy a processzorban milyen áramkörök és milyen utasítások vannak megvalósítva az már a processzor tervezőjének a fantáziájától függ. (abba nem megyünk bele most, hogy léteznek ún. mikroprogramozott processzorok de a lényeg hasonló).
Gépi kód - Assembly nagyjából a Gépi kódhoz az assembly nyelv áll a legközelebb, az úgy van megalkotva, hogy egy assembly utasítás egy gépi kódú utasításnak felel meg. Annyi "trükk van", hogy az assembly fordító pár kényelmi dolgot biztosít (pl. lehet nevet adni az egyes memória címeknek és nem a címeket kell fejben tartani kb. megfelel a változó névnek; a legtöbb tud olyat, hogy gyakran használt "részeskből" lehet ún. makrókat készíteni és akkor csak leírjuk, hogy ide ezt meg ezt a makrót tedd /intelligens ctrl-c - ctrl-v gyakorlatilag/ azaz csinálok egy olyan makrót, hogy másold B-t az A-ba, majd másold az X memória címen lévő adatot B-be utána add össze A-t és B-t. Hogy ezt ne kelljen leírni 1000x a programban tudok definiálni egy ilyen makrót és a fordító ahol kell "kifejti").
És, hogy mihez fér hozzá egy gépi kódu program? Korszerű processzoroknál attól függ milyen "szinten" fut a program. (itt megint proci függő, hogy ezeket minek nevezik). Ez az első lépés a rendszer biztonsága számára. Pl. hiába írok gépi kódban egy programot ha az olyan "szinten" fut akkor ott védelmi exception fog történni ha olyat akartok tenni ami számomra nem engedélyezett. Ezt ki is használják a "modern" operációs rendszerek (úgy nagyjából 1960-as évek közepe óta). Ez megfelelő hardver támogatás nélkül nm működik (ld. pl. unixoknál a "segmentation fault" vagy a windowsnál a "general proteciton fault" hibaüzenetek ha túl címzek). De lehetnek olyan utasítások is amiket pl. egy felhasználó ki sem adhat a programjából, mert azt csak másik szinten lehet végre hajtani. Mondjuk erről heteket lehet beszélni. De ma már erre egyre kevésbé van szüksége egy átlagos programozónak sem, de felhasználónak még kevésbé. Kb. már csak azoknak érdekes akik a procit tervezik.
"Ez eszetlen nagy baromság már bocs. Ez kb. a 8 bites mikroprocikra volt igaz valamikor kb. 45-50 évvel ezelőtt. Égtelen szamárság és tévedés."
Nem baromság. Miért lenne baromság? Egy 486-os procira, vagy egy pentium III-ra, i5-re miért ne lenne igaz?
Amúgy, az égtelen, az helyesen: ÉKTELEN.
Sztem a kérdező itt arra gondolt hogy hogyan fut le a program.
Röviden a CPU sok sok kapukból és órajelből áll.
Amit írsz program azokat atomi részekre lehet bontani ami végül 0 és 1 esek sorozatává válik. És ezekkel kezd egyszerű számolásokat csinálni (összeadás, kivonás, szorzás, osztás(nem mindig van jelen) és a különböző kapuk mint és vagy, xor , nem stb)a processzor aminek az eredményét vissza lehet fordítani.
További kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!