Szerző Téma: (Leírás) A DeAMX, és hogy miért "nem mûködik".  (Megtekintve 1222 alkalommal)

Nem elérhető krisk

  • 2380
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Dátum: 2013. Január 02. - 10:37:28 »
+9 Show voters
BEVEZETÉS
Mostanában a SAMP fórumon nagyon fellendült a gépi kód alacsony szintû programozása. Mivel egy ideje én is foglalkozok ezzel, és a DeAMX mûködése a kezdõ scriptereknek rejtély, ezért írtam meg a tutorialt. A tutorial, hiszen kezdõknek készült, koránt sem teljes és nem feladata a megfelelõ szaknyelv használata.
Remélem, aki PAWN-ban scriptel, az tisztába van azzal, hogy a PAWN, mint olyan, egy programozási nyelv. Az általunk kifejezett utasításokat gépi kódokká alakítja. Míg az emberek a szöveges nyelvet egyszerûbben, és hatékonyabban tudják kezelni, a gépek a számokat preferálják. Ezt nevezzük gépi kódnak.
Ellentétben a közhiedelemmel, a gépi kód nem teljesen értelmetlen zagyvaság, hiszen akkor a számítógép se értené meg. Ellenben igen nehéz olvasnia egy ismeretekkel nem rendelkezõ felhasználónak. Ahhoz, hogy megértsük a problémát, tudnunk kell, mit nevezünk magas és alacsony szintû programnyelveknek. A magas szintû programnyelvek az emberek számára érthetõbbek, jobban programozhatóak, viszont a fordításuk erõforrásigényesebb, a program futása az alsóbb rétegek miatt általában lassabb. Az alacsonyabb szintû nyelvek az ember számára kevésbbé érthetõbbek, viszont gépi kóddá elõbb fordítódnak (hiszen közelebb állnak hozzájuk), és gyorsabbak.
A PAWN, mint olyan, egy magas szintû nyelv, az ember számára könnyen olvasható, és megérthetõ.
 

   new var = 15;
   while (var > 0)
   {
      var = var - 1;
   }

 
A fenti scriptet, ha lefordítjuk, egy futtatható fájlt kapunk (AMX). Az AMX gépi kód, ezért megértése lehetetlen, ha nem ismerjük a felépítését. Ebben segít nekünk az ún. assembly nyelv. Az assembly a legalacsonyabb szintû programozási nyelv: a gépi kód felett állva az egyik legbonyorultabb, de leggyorsabban forduló és a gép számára legésszerûbb nyelv.
A PAWN fordító -a kapcsolójával az AMX helyett ASM (assembler) kódot kapunk. Ha valakit érdekel, nyisson egy parancssort rendszergazdaként, navigáljon el a pawno mappájába, majd üsse be a pawncc fájlnév -a parancsot, ahol a fájlnév értelemszerûen a kódunk neve. Ne feledjük, hogy az assembly minden architektúrán változik, az AMX-nek (ami egy absztrakt gép, tehát egy szimulált számítógép) más fajta assemblyje van, mint egy x86-os processzornak. Ha a gépi kódot szeretnétek megtekinteni változatlanul, dobjatok egy #pragma compress 0-t a módban, és a tiszta kódot kapjátok meg a hex editorban. Én is így csináltam a gépi kódokhoz a példákat.
A fenti PAWN kód így néz ki az AMX assemblyjében:
 

break
push.c f
break
l.0   
break
load.s.pri fffffffc
move.alt
zero.pri
jsgeq 1
break
load.s.pri fffffffc
add.c -1
stor.s.pri fffffffc
jump 0
l.1

 
És miért mondjuk azt, hogy a gépi kódhoz a legközelebb áll? Egészen egyszerûen azért, mert minden egyes utasítás a gépi kódban megfelel egy két hexadecimális számból álló opkódnak, az utánna álló paraméterek pedig az opkód után álló hexadecimális számoknak.
 

89 00 00 00 |           // break

 


27 00 00 00 | 0F 00 00 00 // push.c f

 
Látszódik a fenti két kódrészletbõl, hogy az assemblybõl gépi kódot képezni nem éppen komoly munka. Az utasítást az elsõ négy, míg a paramétereket az utolsó négy bájtban tárolja el. Még ha az utasítás (vagy szebben fogalmazva opkód) csak 1 bájtot (0x00 - 0xFF) foglal el, a maradék három bájtot a kötelezõ formátum miatt nullákkal kell kitölteni. Az utasítás négy bájtja és a paraméterek négy bájtja közé húztam egy vonalat, ez az eredeti gépi kódban nincs ott. Látható hogy a break utasítás opkódja 89, a többi nulla csak a kötelezõ 4 bájt kitöltésére van.
Ugyanígy a második példánál a 27 a push.c opkódja, majd a 4 üres bájt a kötelezõ formátum miatt van. A paramétere 0F, a maradék három bájt a kötelezõ formátum miatt itt is zérus.
A VÁLTOZÓK MIZÉRIÁJA
Amennyiben valaki már próbált DeAMX-el kódot visszafejteni, rájöhetett, hogy nem éppen jönnek vissza a változónevek, helyette értelmetlen var0, var4, var16, és egyéb értékeket kap. A helyzet a következõ: a számítógépek nem szeretik a szöveget: bonyorultak, sok memóriát foglalnak, lassítják a kódot, az embereknek viszont jobban megjegyezhetõ, mint egy rakat hexadecimális szám. Viszont a PAWN kód nem arra van, hogy visszafejtsed.
 

load.s.pri fffffffc    03 00 00 00 FC FF FF FF
add.c -1               57 00 00 00 FF FF FF FF
stor.s.pri fffffffc    11 00 00 00 FC FF FF FF

 
A fenti kód betölti az 0xfffffffc memóriacím alól a változót, csökkenti az értékét eggyel, majd eltárolja az új értéket a memóriacímben. Mellé írtam a gépi kód azon részét, ahol ez lejátszódik. Láthatjuk, hogy a load.s.pri opkódja a 03, követi három üres bájt, majd az FC FF FF FF felel meg a 0xFFFFFFFC-nek. A gépi kódoknál a hexadecimális számok bájtonkénti fordított sorrendben kerülnek be a listára (lásd Anthony kommentjét). Tehát egy ABCDEF12 hexadecimális szám mint 12 EF CD AB kerül bele a gépi kódba. Ezt hívjuk programozási szaknyelven kis endiánnak.
A második sorban látjuk, hogy az add.c opkódja 57, követi három üres bájt, majd a -1 signed integer hexadecimális megfelelõje: 0xFFFFFFFF. Arról, hogy ez hogyan lesz végül is, ha valaki tájékozódni akar, javaslom Anthony tutorialját a bináris mûveletekrõl.
Végül a módosult értéket ugyanabba a memóriacímbe elraktározzuk.
A lényeg, hogy a fenti kód hasonlít ehhez. Mert hogy pont ugyanaz a kettõ:
 

var = var - 1;

 
És akkor mégis mi az a 0xfffffffc, és miért ez, nem \"var\"?
MEMÓRIACÍMEK, MEMÓRIA LEFOGLALÁSA
Arról már volt szó, hogy a számítógép nem szereti a szöveget, és a PAWN nem arra lett tervezve, hogy visszafejtsék. Ezért eldobja azt, ami nem kell. Vegyük példának az alábbi kódot:
 
new var1;
new var2;
new var3;
new var4;

 
Ezt a DeAMX a következõképpen adja vissza:
 

new var12;
new var8;
new var4;
new var0;

 
Az assembly kódba ugyan nem került bele a három változó, hiszen sosem lettek használva, de kommentekben megtalálhatjuk a nyomát:
 

;$lcl var1 fffffffc
;$lcl var2 fffffff8
;$lcl var3 fffffff4
;$lcl var4 fffffff0

 
Láthatjuk, hogy mind a három változó pontosan 4 bájtot (1 cellát/2 szót) foglal el, hiszen a memóriacímek négyesével növekednek (0, 4, 8, C, 10, 14, 18, 1C, 20, ...).
Ez azért van, mivel a korábbi példákból észrevehetjük, hogy a változó korábbi regiszterbe való betöltésekor és módosításakor is egészen pontosan 4 bájtba kellett beírnunk a szám értékét, levonhatjuk tehát a következtetést, hogy a PAWN integer alapból 32 bit = 4 bájt hosszú. Ez azért van, mivel a PAWN-ban minden alapból 1 cella hosszú (ami elméletileg megegyezne a processzorod architektúrájával, a SAMP azonban csak 32 bit hosszú cellákat használ). Minden adattípus a PAWN-ban maximum 4 bájt hosszú.
Ezt próbálja meg a DeAMX ábrázolni, mikor a változónknak var0, var4, var8, var12, var16... neveket ad. A konkrét számok, és a látszólagos fordított kiosztásuk oka a relatív memóriacímekben rejlik, mégpedig abban, hogy az. ún stack memóriacímei, ahol a függvények lokális változói tárolódnak, lentrõl felfele kerülnek kiosztásra: ezekrõl kissé bõvebben az AMX és memóriaképe c. tutorial foglalkozik.
Ugyanez a helyzet a függvényekkel: memóriacímek alapján azonosítják õket. Az egyetlen kivétel az eljárások esete (callback), melyeknek a helyzete elõre nem tudható, ezért a függvény neve és a függvényre mutató pointer tárolódik el a scriptben.
TAGEK
Miért van az, hogy a
 

new Float:var = 5.7;

 
változó ez lesz fordítás után:
 

new var0 = 1085695590;

 
?
A megoldás itt is egyszerû: a tagek csak a fordító számára érdekesek, a gépi kódnak nem. A tagek csak a fordító számára fontosak, hogy egyféle mûveletet különbözõ adatokkal különbözõképpen használjon. Miután a fordítás megtörtént az adatok rögzítõdnek az IEEE 754 szabványnak megfelelõen (egy szabvány ami leírja a lebegõpontos számok bináris ábrázolását). Mikor a DeAMX visszafejti a kódot, mivel mind a lebegõpontos számok, mind az integerek ugyanúgy tárolódnak, nem tudja, hogy az adott cím alatt integer, vagy float van, ezért integerré alakítja.
A szabvány felépítését nem fogom részletezni, mivel egyrészt bonyorult, másrészt érdektelen a tutoriallal kapcsolatban. Ha valakit nagyon érdekel, keressen rá az interneten a szabványra.
ANTI-DEAMX
Végül egy gyors mondat az anti-deamx-rõl: ezek mindegyike a compiler hibáját használja ki, egyik sem hivatalos, és ha a SAMP-hoz új compiler jönne ki, akkor egyik se érne sokat.
A loopos példa Y_Less tutorialjából van. Észrevételeket szívesen látok.
« Utoljára szerkesztve: 2013. Június 14. - 17:34:54 írta krisk »

Nem elérhető Rupert

  • 2301
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #1 Dátum: 2013. Január 02. - 11:16:34 »
0 Show voters
krisk minõségû leírás. Nagyon szép lett!

Nem elérhető tonyo

  • 1335
  • Moderális Generátor
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #2 Dátum: 2013. Január 02. - 11:40:40 »
0 Show voters
Idézetet írta: krisk date=1357119448\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"31816\" data-ipsquote-contentclass=\"forums_Topic
A gépi kódoknál a hexadecimális számok utolsó két számjegye elõre kerül, sajnos nem tudom, miért, ha valaki esetleg tudná, megköszönném, ha elmondaná.
Ugyan Assemblyben nem vagyok jártas, de erre tudom a választ, részben.
Ha mi ránézünk egy hexadecimális számra, akkor tudjuk, hogy az 4 bit(programozásban). Valamint azt is tudjuk, hogy hátulról kezdjük számolni a biteket. Nos gépi kód az ugyebár a biteket bájtonként csoportosítva ábrázolja. Viszont, nem úgy ábrázol, mint ahogy azt mi megszokhattuk, hanem fordítva.
Tudjuk ugye hogy ha egy Hexadecimális szám pl A2FDC53B, akkor abban a 3B a 1. bit, a C5 a 2. bit, az FD a 3. bit, és az A2 a 4. bit, mivel ugye hátulról kezdjük számolni. A gépi kód minden utasítást bájtokban kap. 1 bájt, az ugye 8 bit. Az 1-4. bit tartalmazza az utasítást, az 5-8. bit pedig a paramétert. Ha megnézzük ugye, egy bit értéke maximálisan 28-1, vagyis 255 lehet. 255 az hexadecimális számokkal ugye FF. Láthatjuk tehát, hogy 2 hexadecimális szám fejez ki 1 bitet. Normál esetben ugye mint tisztáztuk, hátulról számoljuk a biteket, a gépi kódban azonban fordítva, az 1. bit kerül ténylegesen az elsõ helyre, a 2. bit a második helyre, és így tovább. A paraméter elsõ bitje tehát az 5. helyre kerül a második bitje a 6. helyre, és így tovább.
Te itt pont olyan számmal dolgoztál, amelyiknél a 2.-4. bit megegyezik, így nem tûnt fel a változás. Azonban az általam említett A2FDC53B hexadecimális szám gépi kódban így nézne ki (természetesen lenne még elõtte 4 másik bit):
 
3B C5 FD A2

 
Egyébként szép, minõségi leírás, köszönjük :)
« Utoljára szerkesztve: 2013. Január 02. - 11:52:48 írta Anthony »

Nem elérhető krisk

  • 2380
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #3 Dátum: 2013. Január 02. - 11:45:39 »
+1 Show voters
És tényleg, hülye vagyok, az a fránya kis endián, mikor NES stat hackeket csináltam, csak valahogy kiesett. Meg megzavart, hogy a többi bitben csak FF volt. Köszi a segítséget!
« Utoljára szerkesztve: 2013. Március 29. - 08:23:14 írta krisk »

Nem elérhető tonyo

  • 1335
  • Moderális Generátor
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #4 Dátum: 2013. Január 02. - 11:55:38 »
0 Show voters
Nagyon szívesen :)

Nem elérhető krisk

  • 2380
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #5 Dátum: 2013. Január 04. - 19:43:59 »
0 Show voters
EDIT #1
#pragma compress 0-rõl információk, illetve kisebb javítások elvégezve.

Nem elérhető Amf

  • 1459
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #6 Dátum: 2013. Január 04. - 22:19:39 »
0 Show voters
Szokásos krisk. ;)

Nem elérhető Rupert

  • 2301
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #7 Dátum: 2013. Január 08. - 19:33:27 »
0 Show voters
Téma áthelyezve a \"Tanuljunk PAWN nyelvet\" alfórumba a minõségi leírás miatt.


Nem elérhető Shady

  • 313
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #8 Dátum: 2013. Január 09. - 00:18:39 »
0 Show voters
MEMÓRIACÍMEK, MEMÓRIA LEFOGLALÁSA
Arról már volt szó, hogy a számítógép nem szereti a szöveget, és a PAWN nem arra lett tervezve, hogy visszafejtsék. Ezért eldobja azt, ami nem kell. Vegyük példának az alábbi kódot
[/quote]
Bocs az okoskodásért, de itt PAWN helyett nem AMX-et akartál írni? :)
Nekem is tetszik a leírás, de nekem még egy kicsit magas ez.
« Utoljára szerkesztve: 2013. Január 09. - 00:22:22 írta Shady »

(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #9 Dátum: 2013. Január 09. - 07:16:14 »
0 Show voters
Idézetet írta: Shady date=1357687119\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"31816\" data-ipsquote-contentclass=\"forums_Topic

MEMÓRIACÍMEK, MEMÓRIA LEFOGLALÁSA
Arról már volt szó, hogy a számítógép nem szereti a szöveget, és a PAWN nem arra lett tervezve, hogy visszafejtsék. Ezért eldobja azt, ami nem kell. Vegyük példának az alábbi kódot
Bocs az okoskodásért, de itt PAWN helyett nem AMX-et akartál írni? :)
Nekem is tetszik a leírás, de nekem még egy kicsit magas ez.
 
[/quote]
Nem AMX, mivel a PAWN fordítja le a kódot AMX file-ba.
Az AMX file sokkal másabb, nem tartalmazza az eredeti kódot, csak gépi kódokat, Y_Less is írt róla leírást(csak nem tudom holvan), az AMX rövidítése: Abstract Machine eXecutor (AMX)
(sry, ha hibás a válaszom, akkor írjatok mi rossz benne)

(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #10 Dátum: 2013. Január 09. - 14:17:42 »
0 Show voters
Krisk: Te lettél a szememben az új isten... Kár, hogy politeizmusban élek. :D
Felnézek az olyan emberekre, akik valamilyen engem érdeklõ témában magasan felettem állnak. :)

Nem elérhető krisk

  • 2380
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #11 Dátum: 2013. Január 09. - 15:57:14 »
0 Show voters
Idézetet írta: Rupert date=1357670007\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"31816\" data-ipsquote-contentclass=\"forums_Topic
Téma áthelyezve a \"Tanuljunk PAWN nyelvet\" alfórumba a minõségi leírás miatt.


 
Köszönöm az áthelyezést.
 

 

 
MEMÓRIACÍMEK, MEMÓRIA LEFOGLALÁSA
Arról már volt szó, hogy a számítógép nem szereti a szöveget, és a PAWN nem arra lett tervezve, hogy visszafejtsék. Ezért eldobja azt, ami nem kell. Vegyük példának az alábbi kódot
[/quote]
Bocs az okoskodásért, de itt PAWN helyett nem AMX-et akartál írni? :)
Nekem is tetszik a leírás, de nekem még egy kicsit magas ez.
 
[/quote]
Nem AMX, mivel a PAWN fordítja le a kódot AMX file-ba.
Az AMX file sokkal másabb, nem tartalmazza az eredeti kódot, csak gépi kódokat, Y_Less is írt róla leírást(csak nem tudom holvan), az AMX rövidítése: Abstract Machine eXecutor (AMX)
(sry, ha hibás a válaszom, akkor írjatok mi rossz benne)
 
[/quote]
Jól írtad.
Az eredeti kérdésre: itt rámutatnék egy dologra, ami okot adhat a félreértésekre. Én a leírásban felcserélhetõ fogalmakként használtam a .amx és az AMX megnevezéseket. Az AMX egy absztrakt gép (a SAMP világban mint Virtual Machine fut), tehát ugyanúgy lehet programozni mint egy akármilyen számítógépet, csak mivel sandbox jellegû, több architektúrán is elfut (8 bitestõl a 64 bitesig), és persze p-kód, tehát akárhol mûködik akármilyen processzor alatt, sokkal jobb alternatíva. Meg ugye nincs ott az a veszély, hogy valamikor hirtelen dobatsz a Windows-zal egy BSoD-t mert rossz memóriacímekbe turkáltál.
Az .amx az AMX-hez tartozó gépi kód, tehát az .amx-et fejted vissza, de a PAWN nyelvet nem tervezték arra, hogy visszafejtsék (az .amx-bõl). A gépi kód meg pont olyan, hogy egy disassemblerrel lényegében elég nagy hatásfokkal visszafejthetõ, ellentétben egy magas szintû nyelvvel.
Y_Less az #emit-rõl írt egy leírást, magáról az AMX-rõl, mint absztrakt géprõl is volt egy rövid leírás, arról is terveztem írni, de nem láttam értelmét, mert a legtöbb részét a leírásnak a memóriakezelési szakszavak vették volna el (heap, stack, csak két egyszerû példának).
 

Krisk: Te lettél a szememben az új isten... Kár, hogy politeizmusban élek. :D
Felnézek az olyan emberekre, akik valamilyen engem érdeklõ témában magasan felettem állnak. :)
 
[/quote]
Azért annyira még én sem vagyok profi, próbálkozom.
« Utoljára szerkesztve: 2013. Március 29. - 08:26:47 írta krisk »

(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #12 Dátum: 2013. Január 11. - 15:16:37 »
0 Show voters
Memóriakezelésnél én a FILO és FIFO-nál megakadtam... krisk, ha van skyped és valamikor ráérsz adhatnál egy kis továbbképzést, mert utálom magam hülyének érezni.

Nem elérhető krisk

  • 2380
    • Profil megtekintése
(Leírás) A DeAMX, és hogy miért "nem mûködik".
« Válasz #13 Dátum: 2013. Január 11. - 22:13:25 »
0 Show voters
Idézetet írta: James_Raynor date=1357913797\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"31816\" data-ipsquote-contentclass=\"forums_Topic
Memóriakezelésnél én a FILO és FIFO-nál megakadtam... krisk, ha van skyped és valamikor ráérsz adhatnál egy kis továbbképzést, mert utálom magam hülyének érezni.
 
Akkor inkább megírom a leírást, és akkor mindenki elérheti meg tanulhat belõle. Valamikor a hétvégén elkészül.
(amúgy amit te írsz az a LIFO, és a stack memóriakezelési alapja: a legkésõbb lefoglalt blokk az, amit legelõször törölnek)
e: kész.
« Utoljára szerkesztve: 2013. Január 12. - 12:40:06 írta krisk »

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal