Assembly/Bevezetés az assemblybe

A Wikikönyvekből, a szabad elektronikus könyvtárból.

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.