Mindegyik C fordító lehetőséget biztosít Assembler utasítások beszúrására a C programunkba. Ennek előnye az, hogy ezen kódrészletek sokkal gyorsabban futnak, mint a C-ben megírt kódok, főleg, ha jól vannak optimalizálva. Ezért legfőképpen optimalizációs célokra szokták használni, illetve speciálisan olyan hardver közeli dolgok kivitelezésére, ami másképp nem lenne megoldható.
Assembly használata az asm „függvény” segítségével lehetséges:
asm("asm kód"
"..."
: "=r"(kimeneti változó)
: "r"(bemeneti operandus)
: "regiszterek"
Nézzünk a használatára egy példát:
#include <stdio.h>
int main()
{
int x = 1;
asm("movl %1, %%eax;"
"movl %%eax, %0;"
: "=r"(x) /* x a kimeneti operandus: %0 */
: "r"(11) /* bemeneti operandus: %1 */
: "%eax"); /* %eax használt regiszter */
printf("x = %d\n", x);
}
A fenti kód Assembly segítségével az x változóba mozgatja a 11 értéket. Ehhez a movl x86 utasítást használja. A %1 helyére a bemeneti operandus kerül behelyettesítésre. Az %%eax pedig a CPU EAX regisztere. A következő utasítás ennek az értékét mozgatja a %0 helyére, ami a visszatérési érték az Assembly blokkunkból. A paraméterezés végén pedig jelezni kell a fordítónak, hogy az EAX regiszter lett használva. Erre azért van szükség, mert a regiszter tartalmát az állapotmegőrzés miatt az Assembly utasítások végrehajtása előtt és után vissza kell állítania a fordítónak.
Az Assembly kód CPU függő, vagyis eltérő CPU típusok között nehezen vagy egyáltalán nem hordozható kódot eredményez. Ezért csak akkor érdemes alkalmazni, hogy ha másként nem megoldható az elérni kívánt funkcionalitás.
Az Intel x86/x64 processzorok programozói kézikönyve a https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html címről tölthető le több változatban. A kombinált leírás (architektúra + utasítások) több, mint 5000 oldal.
Ha a C kódunkból generált Assembly kódra vagyunk kíváncsiak, akkor a https://godbolt.org/ címen található Compiler Explorer tud a feladatban segíteni.