Az első lépések alacsony szintű programozási
Az első lépések alacsony szintű programozási
Mighty eljárás Move
Move - kíváncsi szokásos eljárás, az általunk örökölt inkább a jó öreg Turbo Pascal'ya. Valószínűleg valamilyen hiba került a magas szintű programozási nyelv, de meglehetősen hozzáadott kapacitását és egyszerűsített élet (és mi csak örülünk). Úgy tűnik, hogy semmi különös: eljárás Move (const forrása; var Cél; Count: Integer); Mozog forrása a Cél darab egyenlő Count bájt. És, ahogy te is észrevetted (ha észre), a Forrás / Cél - nem mutató, és a változók közvetlenül, és kiindulópontként Move veszi az első bájt által elfoglalt változó. Nézd meg a példákat: var
b. array [0..80] bájt;
c. array [4..67] char;
w. array [8..670] szó;
eljárás SomeProc;
kezdődik
MessageBox (0, 'hello!' Nil, 0);
végén;
kezdődik
lépés (b, c [4], 20); // másolni 20 byte elejétől a tömb b a tömbben, kezdve a 4. pozícióban.
mozog (B, W, sizeof (b)); // másolatok az egész tömböt b elején a tömb w (vegye figyelembe a típus hibás méretben!)
mozgatni (w [4], W [50], sizeof (szó) * 100); // „kitolja” az értékek 100 és negyedik 50-én összesen egy tömbben (megjegyzés - Forrás és Cél memória területeket fedik egymást!)
lépés (SomeProc, b, sizeof (b)); // másolja SomeProc eljárást kódot a tömb b
.
Elméletileg egy byte másolódik darabokat memória, függetlenül attól, hogy az adatok típusát és méretét. Figyelemre méltó továbbá, hogy az eljárás működik helyesen, ha az adatok az új helyen „fáj” az eredeti. A példákban, definiáljuk a méret a tömb használatával sizeof funkcióval. Ez adja vissza a méret byte-ban vagy adatstruktúrák vagy adattípus. Jegyezzük meg, hogy nem nyújt semmilyen ellenőrzés túllépné változók végrehajtásában Move, ami az oka több óvatossággal annak használatát, és mindenféle alacsony szintű trükköket. A negyedik példa csak az egyiket. Ő ma számunkra a legfontosabb, így van.
negyedik példa
Logikusan, betöltődik a memóriába, és a munka program áll kód - az utasításokat a processzor ( „ige”), és az adatokat, hogy ezek az utasítások feldolgozása ( „főnév”). Tárolja a számítógép memóriájában, és a többi egyirányú - a bájtok sorozata. És így a kód néha tekinthető bizonyítéknak. Ha én egy tanár, azt mondanám, hogy élet zajlik „Neumann elv” ilyen esetben. A különböző egyedi programok (fordítók, futásidejű csomagolók futtatható fájlok, mindenféle védelem stb) nem tud nélküle. Ezek a módszerek akkor lehet érvényesnek tekinteni előjoga alacsony szintű nyelvek (elsősorban a szerelés), de Delphi és képes elvégezni néhány érdekes kísérletet ilyen.
Most közelebb példánk. B tömb teljes képviseletét SomeProc eljárások a számítógép memóriájában. Sőt, nem tudjuk, hogy hány bájt vesz fel - a legvalószínűbb, alapján a miniatűr, a végén a tömb lesz szemetet - egy darab egy másik eljárás vagy adatokat. De ha az eljárás több, nem férne be a kijelölt 80 bájt. Mint látható: folyamatos bizonytalanság, de megpróbálunk némi fényt a helyzetet. Az első dolog, ami eszébe jut -, hogy mi még mindig beiratkozott a tömbben. Ez teljesen ésszerű! Ön valószínűleg már írt valami hasonló az i: = Low (b) Magas (b) do
Memo1.Lines.Add (IntToStr (i) + '-' + IntToStr (b [i]));. értetlen szemmel és nézd meg a számokat az oszlop.
Azok, akik nem írja a lehető leggyorsabban, a számlap, és nem hagyja ki a lehetőséget, néhány kikötéssel. Pascal lehetővé teszi, hogy bármilyen határok indexelt tömbök (ami annak a jele, „magas szintű” nyelv - például C, minden tömb indexelése nulla). A Delphi tovább ment, és bevezette funkciók alacsony és magas, amelyek meghatározzák a felső és alsó indexek a tömb, ill. Ez tényleg jó, ezért azt javasoljuk, hogy az egész programot, hogy használja őket, megszabadulni a lényegtelen állandó.
Így egy oszlopot a számok. Semmi, mint érdekes. De azt javaslom, hogy ne csak következtetni kódot, hanem egy szimbolikus ábrázolása a byte. Ennek eredményeként, mi írjuk a következőket: i: = Low (b) Magas (b) do
Memo1.Lines.Add (IntToStr (i) + '-' + IntToHex (b [i], 2) + '' + chr (b [i])); Felhívjuk figyelmét, - most használunk a funkció IntToHex IntToStr. Beletelik egy számnak a karakteres ábrázolása hexadecimális. Az első érv eljuttatni a puszta száma, a második - elvárjuk a karakterek számát a kívánt ábrázolás. Professzionális programozók nagyon szeretik hexadecimális jelöléssel. Először is, hogy leírja azt az értékét egy bájt elég csak két karakter. És másodszor, a bájtok csoportosítására együtt egy szót (2 bájt) és dupla szó (4 byte), hogy képes legyen a számoknak nagyobb, mint 255. Most a kihívás előttünk, hogy melyik szám a gépi szó, amely 2-x bájt (a sorrend fontos!). Meg kell kiszámítani: 28 * 256 + 86 = 7254. De ha egy 16-chnuyu (ne szeretné, hogy ismételje meg a „farok a” szót) rendszer, a szükséges számú, hogy egy egyszerű „kötés”. Ie ebben az esetben = 1C56! Még több nyilvánvalóan annak előnyeit jelennek meg, amikor a számot kell a másik irányba, az „oszd meg” a bájt.
Szóval, megint visszatérünk a banán. Futtassa a programot, és vizsgálja meg az eredményt óvatosan. A bájt a 14., a 19. (kifejezni magát a 16-ed rendű, bocs-c) található a vonal „hello!”. Egyre melegebb lesz. Jegyezd meg, hogy végződik a byte-kód nulla, az úgynevezett „null-terminált.” Tehát sorokba C programok. A fordító úgy találta, hogy a függvény neve (MessageBox), amelynek argumentum egy karakterlánc a stílus C (a terminológia az felel meg a típusát Delphi PChar). És így, ahelyett, hogy a meglehetősen bonyolult belső ábrázolása „Pascal”, kialakult a szükséges „sishnuyu”.
Rajta, mélyebbre ásni. Hogy van az, hogy meghatározza, hogy hány bájt a SomeProc? Ehhez szüksége van egy kis változás: eljárás SomeProc;
kezdődik
asm
nop
nop
végén;
MessageBox (0, 'hello!' Nil, 0);
asm
nop
nop
végén;
végén;
A Delphi van egy kényelmes lehetőséget, hogy egészítsék ki a programkód írt darabok teljesen assembly nyelven. Utasítások vannak írva a kulcsszavak ASM és vége, és ki a fordítóprogram a megfelelő helyre a tárgykód változatlan. Mi szükség van csak egy szerelő képzés - NOP (rövidítése: „Nem művelet”), amelynek fő feladata -. Ehhez semmi, és csendben tartsa egyetlen bájtot (neked egy titkot, a kód 90.) Egyesek talán .., rájöttem, hogy mit teszünk az utasítás kétszer elején és a végén mi protsedurki most már elmondhatjuk, az biztos, hogy minden úgy van elrendezve, a két pár byte-kód 90 mi SomeProc két egyforma útmutató - az megbízhatóság, a szelektív nop'y másoktól. természetesen a fordító nem kell csak a TSA vlyat a kódot nem tett nyilatkozatot, de még nincs szükség, hogy helyezze kétszer.
Tehát, dobpergés, futtatni a programot. So-so. Kétszer kilencven legelején - ez azt jelenti, hogy mi van, ha az szükséges. Már jól. Menj előre. Számozott vagy programozók mondani 1B elmozdulás lásd a második pár, úgyhogy mi találtuk eljárás felvesz 19 bájt! Csak mi a fene? String 'hello!' e határokon belül, nem! De a húr belül az eljárás, ezért a végén kiderült, hogy kívül? Itt van, ahogy az várható volt, költözött négy bájt képest az előző pozíció (adtunk összesen 4 nop'a), de ezen kívül! Ezért szükséges, hogy egy fontos következtetés: annak ellenére, hogy a forráskód a program információs és utasítások mellett egy futó program, vannak elválasztva, mindegyik a saját helyén (indít külön, szeletek, tudod.).
Most, csináljuk egy kísérlet: nem hagyja, hogy a fordító önkényesen osztja a helyét a sorban, és csináld magad, és meglátjuk, mi történik. SomeProc vált, mint: Eljárás SomeProc;
const
s: array [0..7] char = 'hello!' # 0;
kezdődik
asm
nop
nop
végén;
MessageBox (0, s, nulla, 0);
asm
nop
nop
végén;
végén;
A program futtatásához, és mit látunk? Bár nem tűnik el otthonukat, hogy egy ismeretlen helyre! Tegye még egy következtetés: Az adatok a különböző helyeken, és ezeken a helyeken függ, aki oda őket - a fordító vagy a programozó. Talk Talk, hanem egy egész sor valahol kapott fényes nappal. Ez minden bizonnyal meg kell találni!
Némó nyomában
Volt egy asztal három oszlop, valami hasonló a miénk veled a közelmúltban vizsgálták. Az adatok közül a középső és a jobb oldali - hexadeciális kódok és szimbólumok, mint volt. Egy látható a bal oldali oszlopban eltolás.
Nyomja meg az Alt + G, ugrik az elmozdulás. Tehát, belépünk az első - 00450C28, és azonnal - sok szerencsét! Karakterlánc megtalálható. By the way, kiderült, hogy 450C2868 offset nem tartozik a mi program (ellenőrzés). Kiváló, egy kolléga, ezért ebben az esetben megfejteni.
Itt talán, és fejezzük be a szórakoztató (remélhetőleg) a narratíva (újra, remélhetőleg) segít, hogy nézd meg programozás egy másik szempontból, és megnyitotta a vágy, hogy az „alacsony szintű kutatást.” Nos, ha így van, írj nekem, hogy érdekli, és remélem, hogy hamarosan folytatódik. Maradj egészséges!