Встраиваемая ассемблерная вставка
Встраиваемая ассемблерная вставка (как правило, вводимая ключевым словом asm) предоставляет возможность встраивать исходный код языка ассемблера в программу на языке C.
В отличие от C++, встраиваемая ассемблерная вставка в C рассматривается как расширение. Она поддерживается условно и определяется реализацией, что означает, что она может отсутствовать и, даже если предоставляется реализацией, не имеет фиксированного значения.
Синтаксис
asm ( строковая_литераль ) ; |
Объяснение
Этот тип синтаксиса встраиваемой ассемблерной вставки принимается стандартом C++, и называется asm-декларацией в C++. строковая_литераль обычно представляет собой небольшую программу, написанную на языке ассемблера, которая выполняется всякий раз, когда выполняется эта декларация. Различные компиляторы 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);
// the definition of func is written in assembly language
__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's extended inline assembly
__asm__ ("leal (%0,%0,4),%0"
: "=r" (n)
: "0" (n));
printf("7*5 = %d\n", n);
fflush(stdout); // flush is intentional
// standard inline assembly in C++
__asm__ ("movq $60, %rax\n\t" // the exit syscall number on Linux
"movq $2, %rdi\n\t" // this program returns 2
"syscall");
}Вывод:
7*5 = 35
Ссылки
- Стандарт C23 (ISO/IEC 9899:2023):
- J.5.10 Ключевое слово asm (с. TBD)
- Стандарт 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 декларации |
Внешние ссылки
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/asm