Assembly/Bevezetés az assemblybe
Az alábbiakban egy egyszerű Helló világ! programon mutatjuk be az assembly nyelvet. Nem túl meglepő módon az alábbi kód a "Helló világ!" üzenetet írja a képernyőre.
segment .code global _start _start: mov edx, len mov ecx, msg mov ebx, 1 mov eax, 4 int 80h mov ebx, 0 ; A program terminálása. mov eax, 1 int 80h segment .data msg db "Hello vilag!", 0ah len equ $-msg
Az assembly programok alapegysége a sor. Egy sorban egy elemi utasítás található (a továbbiakban az utasítás a sor szinonimája lesz). Az elemi utasítás tényleg elemi abban az értelemben, hogy a processzor számára közvetlenül végrehajtható. A processzoron belül persze ezek az utasítások is részekre osztódnak, de a program szempontjából az assembly utasítások oszthatatlanok. Az assembly nyelv(ek) tehát arra való(k), hogy a számítógépet a legalacsonyabb szinten, a gépi kód szintjén programozzuk. Valójában az assembly alig több, mint olvasható gép kód. (Azért valamivel több, mint később majd látjuk.)
Az assemblyből hiányoznak a magasszintű programozási nyelvekre jellemző, az absztrakciót támogató eszközök is, például az objektumorientáltság, de szigorú értelemben még a függvények is hiányoznak belőle. Az eddigiek alapján leszögezhetjük, hogy az assemblyből hiányzik... minden. Miért érdemes mégis foglalkozni vele?
Számos okunk lehet arra, hogy az assemblyt válasszuk a magasszintű programozási nyelvekkel szemben egy konkrét feladat megoldására:
- Pontosan tudni akarjuk, hogy mi történik a program futása közben. Mi akarjuk eldönteni, hogy mi kerüljön a kódba és mi ne. Nagy biztonságú rendszerek írásakor elengedhetetlen, hogy egészen pontosan tudjuk, hogy mi történik, külnben olyan hibaforrások is maradhatnak, amelyekről nem tudunk.
- Méretre akarjuk optimalizálni a kódot. Egy C++ fordító valószínűleg olyasmit is belefordít a kódba, amit mi nem szántunk oda.
- Sebességre akarjuk optimalizálni a kódot. Teljsesítménykritikus algoritmusokat, ahol minden nanomásodperc számít, érdemes lehet assembly-ben megírni. Egyrészt a programozó azokat az optimalizálási lehetőségeket is észreveszi, amelyeket a legjobb kódoptimalizáló is figyelmen kívül hagy, másrészt az assembly-vel jobban kihasználhatók az egyes hardverek egyedi utasításai (habár a jobb fordítóprogramok képesek adott hardverre is optimalizálni).
- Hardverközeli programozás. Például a meghajtóprogramokat assembly-ben írják.
- Ami a számítógépen egyáltalán megvalósítható, azt assembly-ben meg lehet írni. Ugyanez nem feltétlenül igaz a magasszintű programozási nyelvekre. Például assembly-ben írhatunk önmódosító kódot (olyan kódot, ami futás közben átírja saját magát). Ugyanezt csak korlátozott mértékben tudjuk megtenni C++-ban, mert nem tudjuk előre, hogy milyen kód fordul a programból.
- Olyan kódot akarunk elemezni és átírni, amit csak gépi kód formájában tudunk megszerezni. Erre leggyakrabban olyankor van szükség, amikor egy nem teljesen legláisan beszerzett programot szeretnénk működésre serkenteni. Lásd később.
- Nem áll rendelkezésre magasszintű programozási nyelv, például egy teljesen új processzortípusra kell kódot írni.
- Olyan esetekben, amikor egy önálló futtatható állományra van szükség, ami nem használ futás idejű és megosztott komponenseket. Ilyenre van szükség beágyazott rendszerek esetében (például egy légkondícionálóhoz).
- Vírusok kódjának visszafejtéséhez, hogy vírusírtó algoritmust tudjunk hozzájuk kidolgozni.
- Vírusok írásához. :) A vírusokat mindig assembly-ben írják, hogy minél kisebbek és gyorsabbak legyenek.
- Fordítóprogram írása. A magasszintű programozási nyelek fordítóprogramjai assembly-kódot állítanak elő. Ha fordítóprogramot akarunk írni, ismernünk kell az assembly nyelvet.
Azonban mindenekelőtt azért érdemes assemby-t tanulni, hogy közelebbről megismerjük a számítógépek működési elvét. Ez által magasszintű programozási nyelvekben is jobb kódot tudunk írni.