close
Пространства имён
Варианты
Действия

Встраиваемое ассемблирование

Материал из cppreference.com

Встраиваемое ассемблирование (обычно вводимое с помощью ключевого слова asm) даёт возможность встраивать исходный код на ассемблере в программу на C.

В отличие от C++, встраиваемое ассемблирование в C рассматривается как расширение. Оно условно поддерживается и определено реализацией, что означает возможность присутствия и, даже если предоставляется реализацией, оно не имеет фиксированного значения.

Синтаксис

asm ( string_literal ) ;

Объяснение

Этот вид синтаксиса встраиваемого ассемблирования принимается стандартом C++ и называется asm-объявление в C++. string_literal это обычно короткая программа, написанная на языке ассемблера, которая выполняется каждый раз, когда выполняется это объявление. Различные компиляторы C имеют широко различающиеся правила для asm-деклараций и различные соглашения для взаимодействия с окружающим кодом на C.

asm-объявление может появляться внутри блока (тела функции или другой составной инструкции), и, как все другие объявления, это объявление может также появляться вне блока.

Замечания

MSVC не поддерживает встраиваемое ассемблирование на процессорах ARM и x64 и поддерживает только формат, вводимый __asm, на процессорах x86.

При компиляции в режиме ISO C в GCC или Clang (напр., с параметром -std=c11) нужно использовать __asm__ вместо asm.

Примеры

Демонстрирует два вида синтаксиса встроенного ассемблирования в компиляторе, предлагаемых компилятором GCC. Эта программа будет работать корректно только на платформе x86-64 под Linux. Обратите внимание, что "стандартное встраиваемое ассемблирование" также рассматривается как расширение стандарта C.

#include <stdio.h>

extern int func(void);
// определение func написано на языке ассемблера
__asm__(".globl func\n\t"
        ".type func, @function\n\t"
        "func:\n\t"
        ".cfi_startproc\n\t"
        "movl $7, %eax\n\t"
        "ret\n\t"
        ".cfi_endproc");

int main(void)
{
    int n = func();
    // расширенное встраиваемое ассемблирование в gcc
    __asm__ ("leal (%0,%0,4),%0"
           : "=r" (n)
           : "0" (n));
    printf("7*5 = %d\n", n);
    fflush(stdout); // намеренный flush

    // стандартное встраиваемое ассемблирование в C++
    __asm__ ("movq $60, %rax\n\t" // выход по syscall с числом в Linux
             "movq $2,  %rdi\n\t" // эта программа возвращает 2
             "syscall");
}

Вывод:

7*5 = 35

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2023):
  • J.5.10 Ключевое слово asm (стр. последует)
  • Стандарт C17 (ISO/IEC 9899:2018):
  • J.5.10 Ключевое слово asm (стр. 422)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • J.5.10 Ключевое слово asm (стр. 580)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • J.5.10 Ключевое слово asm (стр. 512)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • G.5.10 Ключевое слово asm

См. также

Документация C++ по объявлению asm

Внешние ссылки

1.  Встраиваемое ассемблирование в GCC
2.  Встраиваемое ассемблирование в IBM XL C/C++
3.  Встраиваемое ассемблирование в Intel C++
4.  Встраиваемое ассемблирование в Visual Studio
5.  Инструкции ассемблера в Sun Studio 12
6.  Встраиваемое ассемблирование в для HP-UX на базе Itanium