Szerelőbetét

A programozásban az inline assembler a fordító azon képességére utal, hogy az assemblerben írt alacsony szintű kódot magas szintű nyelven , például C vagy Ada nyelven írt programba ágyazza be . Az összeszerelő betétek használata a következő célokat szolgálhatja:

Példa optimalizálásra és speciális processzorutasítások használatára

Ez a példa az assembler beszúrására a D programozási nyelvben , amely megvalósítja az x tangensének kiszámítását, x86 FPU utasításokat használ . Ez a kód gyorsabban fut, mint a fordító által generált kód. Ezenkívül az itt található utasítást használjuk fldpi, amely a legközelebbi számközelítést tölti be az x86 architektúrához.

// Kiszámítjuk x tangensét valós tan ( valós x ) { asm { fld x [ EBP ] ; // betöltés x fxam ; // páratlan értékek tesztelése fstsw AX ; sahf ; jc trigerr ; // x a NAN, a végtelen vagy üres // A 387-ek képesek denormálokat kezelni SC18 : fptan ; fstp ST ( 0 ) ; // X kiírása, ami mindig 1 fstsw AX ; sahf ; jnp Lret ; // C2 = 1 (x a tartományon kívül van) // Az argumentumcsökkentés végrehajtása az x tartományba kerüléséhez fldpi ; fxch ; SC17 : fprem1 ; fstsw AX ; sahf ; jp SC17 ; fstp ST ( 1 ) ; // pi eltávolítása a veremből jmp SC18 ; } trigerr : real . _ nan ; Lret : ; }

Rendszerhívási példa

Az operációs rendszer közvetlen elérése általában nem lehetséges védett memóriával. Az operációs rendszer privilegizáltabb szinten fut (kernel mód), mint a felhasználó (felhasználói mód). Az operációs rendszer felé irányuló kérésekhez szoftveres megszakításokat használnak. A magas szintű nyelvek ritkán támogatják ezt a funkciót, ezért a rendszerhívási interfészek inline assembler segítségével íródnak [1] .

A következő C példa az AT&T GNU Assembler szintaxisával írt rendszerhívási interfészt tartalmaz . Először nézzük meg az assembler beszúrási formátumát egy egyszerű példa segítségével:

asm ( "movl %ecx, %eax" ); /* áthelyezi az ecx tartalmát az eax-be */

Az asmés __asm__az azonosítók egyenértékűek. Egy másik egyszerű beillesztési példa:

__asm__ ( "movb %bh, (%eax)" ); /* áthelyezi a bájtot bh-ból az eax által jelölt memóriába */

Egy példa a rendszerhívási interfész megvalósítására:

extern int errno ; int funkciónév ( int arg1 , int * arg2 , int arg3 ) { int res ; __asm__ volatile ( "int $0x80" /* kérje az operációs rendszert */ : "=a" ( res ), /* eredményt ad vissza az eax-ben ("a") */ "+b" ( arg1 ), /* adja át az arg1-et ebx-ben ("b") */ "+c" ( arg2 ), /* adja át az arg2-t ecx-ben ("c") */ "+d" ( arg3 ) /* adja át az arg3-at az edx-ben ("d") */ : "a" ( 128 ) /* átadja a rendszer hívószámát az eax-ban ("a") */ : "memória" , "cc" ); /* bejelenti a fordítónak, hogy a memória- és feltételkódok módosultak */ /* Az operációs rendszer hiba esetén negatív értéket ad vissza; * A wrappers hiba esetén -1-et ad vissza, és beállítja az errno globális változót */ if ( -125 <= res && res < 0 ) { errno = -res ; _ res = -1 ; } return res ; }

Kritika

A 21. század eleje óta az assembler betétek használatát többféle ok miatt egyre inkább elítélik [2] [3] :

  • A modern optimalizáló fordítók jobb összeállítási kódot tudnak generálni, mint amit egy átlagos programozó meg tud írni. Önmagukban az assembler beillesztések zavarhatják a kód más részeinek optimalizálását. Néhány trükk, amely lehetővé tette a kód végrehajtásának optimalizálását az 1980-90-es évek processzorain a későbbi processzorokon, a végrehajtás jelentős lelassulásához vezethet a számítások eltérő szervezése miatt. Mint minden optimalizálásnál , az összeszerelő lapkákat is tesztelni kell , hogy teszteljük a hatékonyságukra vonatkozó hipotézist. A számítástechnikai rendszerek teljesítményének növekedése miatt sok optimalizálás irreleváns lehet, és előtérbe kerül a kód olvashatósága, a karbantartás egyszerűsége, a hibamegelőzés.
  • Az összeállítási kód írása időigényesebb. Az összeszerelő betétben könnyű hibázni, amit nehéz észrevenni. Például az assembly nyelv nem támogatja a típusellenőrzést . A már generált összeállítási kódot nehezebb karbantartani .
  • Az összeállítási kód nem hordozható. Az összeszerelő betétek a platformspecifikus mechanizmusokhoz való hozzáféréshez indokoltak. Ha többplatformos programokban assembler beszúrásokat használunk , akkor a különböző platformokhoz szükséges assembler beillesztéseket megkettőzni, és lehetőség szerint egy alternatív implementációt is megtartani magas szintű nyelven – ez a gyakorlat azonban problémákat okoz a program karbantartása során a párhuzamosan kell változtatásokat végrehajtani a különböző nyelveken írt kódrészleteken, nyelveken és különböző platformokon.

Jegyzetek

  1. 1 2 "Linux programozás" 5. fejezet A rendszerhívások működése . Opennet. Hozzáférés időpontja: 2013. szeptember 29. Az eredetiből archiválva : 2013. október 2.
  2. Az assembler betétek használatának elemzése a nyitott projektek kódjában . opennet . Letöltve: 2022. május 3. Az eredetiből archiválva : 2022. május 3.
  3. Okok, amiért NE használd az inline asm-t . Letöltve: 2022. május 3. Az eredetiből archiválva : 2022. április 28..

Linkek