Montážní vložka

V programování inline assembler odkazuje na schopnost kompilátoru vložit nízkoúrovňový kód napsaný v assembleru do programu napsaného v jazyce vysoké úrovně , jako je C nebo Ada . Použití vložek assembleru může sledovat následující cíle:

Příklad optimalizace a použití speciálních instrukcí procesoru

Tento příklad vkládání assembleru v programovacím jazyce D , který implementuje výpočet tečny x, používá instrukce x86 FPU . Tento kód běží rychleji než kód, který by mohl vygenerovat kompilátor. Také je zde použita instrukce , která načte nejbližší číselnou aproximaci pro architekturu x86. fldpi

// Vypočtěte tangens x real tan ( real x ) { asm { fld x [ EBP ] ; // načíst x fxam ; // test na liché hodnoty ​​fstsw AX ; sahf ; jc trigerr ; // x je NAN, nekonečno nebo prázdné // 387 si poradí s denormaly SC18 : fptan ; fstp ST ( 0 ) ; // výpis X, což je vždy 1 fstsw AX ; sahf ; jnp Lret ; // C2 = 1 (x je mimo rozsah) // Proveďte redukci argumentu, aby se x dostalo do rozsahu fldpi ; fxch ; SC17 : fprem1 ; fstsw AX ; sahf ; jp SC17 ; fstp ST ( 1 ) ; // odebrání pi ze zásobníku jmp SC18 ; } trigerr : return real . nan ; Lret : ; }

Příklad systémového volání

Přímý přístup k operačnímu systému obecně není s chráněnou pamětí možný. OS běží na privilegovanější úrovni (režim jádra) než uživatel (režim uživatele). K odesílání požadavků na OS se používají softwarová přerušení. Zřídka jazyky na vysoké úrovni podporují tuto funkci, takže rozhraní systémových volání jsou psána pomocí inline assembleru [1] .

Následující příklad C obsahuje rozhraní systémového volání napsané pomocí syntaxe GNU Assembler společnosti AT&T . Nejprve se podívejme na formát vložení assembleru na jednoduchém příkladu:

asm ( "movl %ecx, %eax" ); /* přesune obsah ecx do eax */

Identifikátory asma __asm__jsou ekvivalentní. Další jednoduchý příklad vložení:

__asm__ ( "movb %bh, (%eax)" ); /* přesune bajt z bh do paměti označené eax */

Příklad implementace rozhraní systémového volání:

extern int errno ; int název funkce ( int arg1 , int * arg2 , int arg3 ) { int res ; __asm__ volatilní ( "int $0x80" /* odešle požadavek na OS */ : "=a" ( res ), /* vrátí výsledek v eax ("a") */ "+b" ( arg1 ), /* předat arg1 v ebx ("b") */ "+c" ( arg2 ), /* předat arg2 v ecx ("c") */ "+d" ( arg3 ) /* předat arg3 v edx ("d") */ : "a" ( 128 ) /* předání systémového telefonního čísla v eax ("a") */ : "paměť" , "cc" ); /* oznámí kompilátoru, že paměť a stavové kódy byly upraveny */ /* Operační systém vrátí zápornou hodnotu při chybě; * wrappery vrátí -1 při chybě a nastaví globální proměnnou errno */ if ( -125 <= res && res < 0 ) { errno = -res ; _ res = -1 ; } return res ; }

Kritika

Od začátku 21. století je používání assemblerových vložek z různých důvodů stále více odsuzováno [2] [3] :

  • Moderní optimalizační kompilátory jsou schopny generovat lepší assembler, než dokáže napsat průměrný programátor. Vložky assembleru mohou samy o sobě zasahovat do optimalizace jiných částí kódu. Některé triky, které umožnily optimalizovat provádění kódu na procesorech 80. až 90. let na pozdějších procesorech, mohou vést k výraznému zpomalení provádění v důsledku odlišné organizace výpočtů. Stejně jako u každé optimalizace je třeba otestovat vložky assembleru, aby bylo možné otestovat hypotézu o jejich účinnosti. Vzhledem ke zvýšení výkonu výpočetních systémů může být mnoho optimalizací irelevantních a do popředí se dostává čitelnost kódu, snadná údržba a prevence chyb.
  • Sestavení kódu je časově náročnější na psaní. Ve vložce assembleru je snadné udělat chybu, které je těžké si všimnout. Jazyk symbolických instrukcí například nepodporuje kontrolu typu . Již vygenerovaný kód sestavení je náročnější na údržbu .
  • Kód sestavy není přenosný. Montážní vložky jsou opodstatněné pro přístup k mechanismům specifickým pro platformu. Při použití assemblerových insertů v multiplatformních programech je nutné duplikovat assemblerové inserty pro různé platformy a také, pokud je to možné, ponechat alternativní implementaci v jazyce vyšší úrovně – tato praxe však vytváří problémy při údržbě programu kvůli potřeba provádět změny paralelně v několika částech kódu napsaných v různých jazycích. jazycích a pro různé platformy.

Poznámky

  1. 1 2 "Programování Linuxu" Kapitola 5. Jak fungují systémová volání . Opennet. Datum přístupu: 29. září 2013. Archivováno z originálu 2. října 2013.
  2. Analýza použití assemblerových vložek v kódu otevřených projektů . opennet . Získáno 3. května 2022. Archivováno z originálu dne 3. května 2022.
  3. Důvody, proč byste NEMĚLI používat inline asm . Získáno 3. května 2022. Archivováno z originálu dne 28. dubna 2022.

Odkazy