A C és az assembly.

Azaz kevert nyelv? programozás.

Könnyen szükség lehet rá hardwerközeli prgamozáshoz, vagy olyan programrészletek megírásához, amiknek negyon gyorsnak kell lenniük.

A megoldás technikája többféle is lehet. A legegyszer?bb rögtön a C forráskódba benyomni.

pl.:
        asm mov dx,3dah
        asm out dx,ax

vagy:

asm {

mov dx,3dah

out dx,al

}

Ez a megoldás nem 'túl elegáns ,azonkívül van egy pár hátránya is. Először is a C fordítók körében korántsem mondható áltálánosnak ez a megoldás. A Borland C éppen tudja, de azt hiszem ezzel ki is merült a kör. Az utasításkészlettel is szoktak bajok lenni, hiszen ezzel a módszerrel csak 8086-os utasításkészletet lehet használni. Ez persze nem mindig elég. Aztán a cimkékkel is van baj. Nem lehet az assembly-n belül cimkét deklarálni. tehát:

asm {

cimke:

loop cimke

}

Ezt a fordíto nem fogja megenni.

Persze azért van előnnye is. Egy fileban van a C-vel, így nem kell belelinkelgetni a programba,és könnyen lehet debugolni.

Az igazi megoldás külön file-ba rakni az assemblyt. Ez persze jóval bonyolultabb, de megéri. Egy C alá írt assemblynek valami hasonlóképpen kell kinézni.:

.MODEL SMALL,C ;memóriamodell, nyelv

.286 ;utasításkészlet

EXTRN.n1:tipus ;extern lista
EXTRN n2:tipus

PUBLIC nev1,nev2,nev3 ;public lista

.DATA
adatok...
.CODE
lenyeg..
END

Akkor egy kis magyarázat.:

Az első két soron nincs mit rizsázni. Az extern lista: Azokat a változókat, függvényeket itt kell felsorolni, amiket az assembly használni akar a C-ből. A tipust is meg kell adni, ez lehet byte,word,dword ha változó. Ha c-ben char, akkor byte, ha int akkor word, ha long, akkor dword. Lehet egy C-függvényt is lehet externelni, ilyenkor proc. Public lista : Azokat a függvényeket, változókat itt kell megadni, amit a C lásson az assembly-ből. Tipus nem kell, csak vesszővel felsoroljuk.

Aztán az assembly rutin részéről még vannak kötelezettségek. Menteni kell az általunk változtatott regisztereket, (push a rutin elején) (különös tekintettel az si,di, és a szegmensregiszterekre), de visszaszedni ne felejtsük el(pop), mert ilyenkor csak a reset gomb fog segíteni. Hasonló a helyzet akor is, ha a ret-et felejtük el.

Ennyi lenne az assembly részéről.

De a C-ben is rendezni kell a dolgokat. Ezt legegyszer?bb egy header file-ban megtenni, amit majd include-olunk abban a C-ben ahol az assemblyt használni akarjuk. Az include file:

#ifdef __cplusplus

extern "C"

{

#endif

void fuggvegy(void)

#ifdef __cplusplus

}

#endif

Magyarázat:

A C és a C++ kicsit máshogy kezeli a függvényeket, ezért , ha C++-ban vagyunk, meg kell adni, hogy a függvények C típusúak. Erre szolgál az extern "C"{..........}.

A dolog már rendezve van mind a C, mind az assembly részéről, már csak le kéne fordítani a programot. Ez Borland C-ben a legegyszerűbb, csinálunk egy olyan projektet, amiben benne van az assembly, és a C is. A Borland magától össze fogja linkelni őket. Más fordítórendszereknél külön compile-oljuk a c-t, az assemblyt, majd összelinkeljük azokkal a libekkel amit használ. Persze make filet is írhatunk de ez már nem ide tartozik.
 

Kimmel Tamás
eMail:PC-XUser@IDG.HU, Subject: "abC rovat"
KUMM@MI.STUD.PMMFK.JPTE.HU