Van értelme Assembly programozást tanulni?
Üdv!
Nem olyan rég kezdtem programozni tanulni C#-ban (az egyetemünkön ezzel kezdünk), de azon agyaltam, hogy önszorgalomból (meg mert érdekel is) elkezdenék assembly-vel is foglalkozni.
Nem a válaszaitok alapján fogom elkezdeni/nem elkezdeni, az fix, hogy ha az időm engedi, csinálom.
Inkább arra lenné kíváncsi, hogy ez a tudás érhet is valamit vagy sem?
#Kerdezo
Igen. Van értelme.
(Mas kerdes hogy mennyire tudsz majd anyanyelvi folyekonysaggal beszelgetni a procikkal.)
10: Több ponton nem teljesen igaz amit írtál.
""mert végül is assembly-re fordít minden"
Nem így van. Sokan hiszik ezt, ezért is pontosítok.
A processzor gép kódot ért meg és hajt végre. Minden proci a sajátját. Az assembly nyelv áll a gépi kódhoz a legközelebb, ez tény, de nem azonos vele. "
Igen, de az is igaz, hogy a gépi kód 1:1 megfeleltethető az assemblynek. Azaz gépi kód és assembly között van egy oda-vissza kölcsönösen egyértelmű megfeleltetés (ld. pl. tetszőleges gépikódú program disassemblálható és értelmes assembly nyelvű programot kapsz). Az meg, hogy MOV AX,n vagy MOV BX,n az két külön utasítás lesz, mind a fordító mind a programozó látja,hogy ez két tök különböző utasítás. Az, hogy léteznek "kényelmi okok miatt" szimbolikus assemblerek, és macro assemblerek az már csak a lusta programozónak a "barátja", de vígan le lehet írni bármely assembly kódot szimbólumok nélkül, és az már tényleg akár kézzel is 1-1 fordítható gépi kódra (valamikor fiatal koromban Z80 gépi kód oda-vissza ment kézzel is, a legtöbb utasítás gépi kódja fejből is ment, de kódtáblával a kezemben simán olvastam a gépi kódot, meg írtam is ha kellett).
"Az assembly emellett kötődhet az alkalmazott operációs rendszer és a processzor üzemmódjához is. Az x86 esetében ez lehet valós vagy védett. Ezen túl, van még olyan, hogy memóriamodell. Ezt is figyelembe kell vennie egy processzor assemblerének."
Itt ellentmondásba keverdsz, mert az assembly csak és kizárólag az adott procitól függ. Ez már oprendszer független utasításokat tartalmaz. Az megint egy más kérdés, hogy az oprendszer egyes szolgáltatásait, hogyan lehet eléri assemblyből, de ez nem nyelvi eszköztár kérdése, hanem már implementáció és programozási kérdés. Ugyanígy a memória modell is független itt a nyelvtől. Ez nem olyan mint egy C/C++ forrásprogram, hogy tele van #ifdef CPUTYPE=... és #ifdef OSTYPE=... (vagy ennek tetszőleges "rokonértelmű" testvérkéivel, nesze neked proci és oprendszer független kódolás...). Az, hogy egy adott proci bizonyos utasítása csak bizonyos kontextusban és üzemmódban használhatóak (ld. pl. x86 architektúra protected módú utasításai), megint nem a nyelv sajátossága, hanem egy adott procié. De az utasítás maga, és annak gépi kódja nem változik meg az üzemmódtól max. nem használhatod az adott utasíást (a régi nagygépeken ez még jobban látszott, attól függően milyen "szinten" tudtad futtatni a programodat, más és más dolgokhoz fértél hozzá, pl. nem volt elérhető számodra a fizikai memória, de attól az utasítás nem változott, értelmes volt stb., max. kivágta egy exceptionnel /bár ott nem így hívták, de már nem emlékszem minek nevezték, nagyon régen programoztam nagygépet assemblyben/ az egész progit a gép). De eztől az alapvető nyelvi struktúra nem változik. És ha valaki egy procinak az assemblyjét elsajátította, akkor relatív könnyen tudott "procit váltani". Bár igaz, hogy ez általában a teljes progi újra irását jelentette. Mert nagyon eltérőek az egyes procik. Pl. ha a most divatos PIC mikrokontroller családot nézem (erősen RISC utasításkészletű) van olyan modell ami tud szorozni, van ami nem. Amelyik nem tud, ott kell még egy pár utasítás és meg kell írni a szorzó eljárást. De ezen az ember nem akad fenn, mert az alaputasításokat ismeri.
Viszont, hogy segítsek a kérdezőnek is, talán pont ezért éri meg tanulni legalább egy kis assemblyt, hogy az ember lássa, hogy egy-egy utasítás mögött mi van. Pl. egy szorzás hogyan hajtható végre, hogyan lehet kiszámolni, mondjuk egy olyat, hogy y=a^b hatvány, ahol a és b is valamilyen float. Eleve ha nincs float összeadó utasítás az utasításkészletben már maga a lebegőpontos összeadáson is lehet gondolkodni egy picit. De pont ez az izgalom benne szerintem.
12:
"Azaz gépi kód és assembly között van egy oda-vissza kölcsönösen egyértelmű megfeleltetés (ld. pl. tetszőleges gépikódú program disassemblálható és értelmes assembly nyelvű programot kapsz)."
Nem olyan egyértelmű az a megfeleltetés, mert ha így volna, akkor bármi disassemblálható lenne és a disassembler által kiköpött kód lefordítható lenne egy assemblerrel, csak hát, ez általában nincs így. De azt hiszem ezt nem csak én, hanem te is nagyon jól tudod. :)
"Itt ellentmondásba keverdsz, mert az assembly csak és kizárólag az adott procitól függ. Ez már oprendszer független utasításokat tartalmaz. Az megint egy más kérdés, hogy az oprendszer egyes szolgáltatásait, hogyan lehet eléri assemblyből, "
Nem keveredek ellentmondásba.
Az assembly mint nyelv, tekintettel kell legyen a processzor üzemmódjára, mert pl. védett módban nincs szegmentálás, tehát ehhez kell alkalmazkodni, de az oprendszer sem azért érdekes, mert az OS szolgáltatásait vagy BIOS rutinokat akarok elérni, hanem az OS memóriakezelésére kell tekintettel lennem. Próbáld ki, ugyanazt a kis nyúlfarknyi assembler programot fordítsd le linux és windows alá.
"És ha valaki egy procinak az assemblyjét elsajátította, akkor relatív könnyen tudott "procit váltani"."
Igen, ebben a lényeget tekintve igazad van. Nem kell újratanulni minden proci után az assembly nyelvet. A tudás jó része átvihető, hasznosítható, mert pl. számlálós ciklust szervezni hasonlóan fog valaki a legtöbb processzoron, legalábbis assemblyben.
Azt meg kell említeni, hogy kivételek itt is vannak, mert akad proci, amelyik alapjaiban rugja fel a korábbi sztenderdeket, ahogy ezt tette annak idején a 6502, vagy még ilyenebb volt a 1802-es. Előbbi a RISC jellegével és kevés reiszterével, utóbbi meg a túl sok regiszterével és architekturális különbözőségével (subrutinok hívása) tűnik ki.
Ezt írod:
" talán pont ezért éri meg tanulni legalább egy kis assemblyt, hogy az ember lássa, hogy egy-egy utasítás mögött mi van."
Na, ez itt a lényeg.
Az assembly annyira hatással van a gondolkodásra, hogy aki valaha assemblyzett, az akkor is jobb kódot fog írni magas szintű nyelven, ha soha többé nem használ assemblert.
"Az meg, hogy MOV AX,n vagy MOV BX,n"
Azt mondod a programozó tudja, hogy ez -két külön utasítás.
Én meg azt mondom, hogy aki ért hozzá az tudja, hogy ugyanaz az utasítás. Az utasítás a MOV. Az AX,BX regiszter, az n altalad megadott változó pedig operandusnak felel meg.
Tehát ugyanaz.
15: LOL
A MOV utasítás az x86 assemblyben 20, azaz húsz darab utasítás gépi kód szinjén, attól függően, hogy az adat micsoda és honnan hova kerül.
13 tegnap 19:29
"Az assembly annyira hatással van a gondolkodásra, hogy aki valaha assemblyzett, az akkor is jobb kódot fog írni magas szintű nyelven, ha soha többé nem használ assemblert."
Ez nem igaz. Mert a korszerű magas szintű nyelvek nagyon-nagyon más gondolkodásmódot követelnek meg. Gondolok itt pl. az objektumokra. És őszintén bevallom, nagyon rossz kódokat írok magasszintű nyelveken, főleg objektum orientált környezetben a sok assembly "hibás" berögződés miatt. 20-on pár éve keringett a neten egy poénos írás, hogy egy "jó programozó bármilyen nyelven képes Fortran programot írni", ezt valahol érzem is magamon, mert sokszor előjönnek az assemblys beütések, amik az adott nyelven nem bztos, hogy hatékonyak (sokszor nem is keresek hozzá esetleg kiegészítőt, nyelvi eszközt stb. hanem megírom, ami lehet, hogy az adott nyelven 2 mozdulat lenne). És az objektum orientált szemlélet annyira távol esik már az assembly gondolkodásmódtól, hogy szerintem ha valaki abba az irányba akar elmenni neki zsákutca is lehet.
16 ma 05:39: kiegészítés, mert nagyon jó amit írtál!
Nem csak gépikód szinten térnek el a különböző MOV utasítások (x86-nál nem néztem, 8085-ön, meg 8088-on néztem ezt részletesen), hanem működésében is, feltételezem, hogy még mindig (8088-on biztosan így volt, ezért feltételezem), hogy a különböző MOV utasításoknak más volt a végrehajtási ideje is. Az, hogy egyszerűsítés kedvéért mindegyiket MOV mnemoiccal jelölik azért van, hogy nekünk programozónak egyszerűbb legyen. De jelölhetné különböző is, mert teljesen eltérő utasításokról van szó. Egészen másképpen kell "implementálni" azokat. Most egy hobby projekt miatt próbálok egy diszkrét CPU-t tervezni (nem mikroprogramozott, hanem huzalozott, kapu áramkörökből, tranzisztorokból és diódákból), és itt áramkör szinten látszik, hogy nagyon másképpen kell ezeket a különböző MOV utasításokat implementálni, és adja is magát, hogy más lesz a végrehajtási idejük. Pl. egy regiszter-regiszter MOV és egy regiszter-memoria MOV egészen másképpen működik.
"Most egy hobby projekt miatt próbálok egy diszkrét CPU-t tervezni (nem mikroprogramozott, hanem huzalozott, kapu áramkörökből, tranzisztorokból és diódákból),"
Ezt a projectet lehet követni valahol?
Mert engem érdekelne.
Kapcsolódó 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!