6.44.1 Основные инструкции ассемблера без операндов
Базовое asm утверждение имеет следующий синтаксис:
asm [ volatile ] ( AssemblerInstructions )
Ключевое слово asm является расширением GNU. При написании кода, который может быть скомпилирован с -ansi и различными -std параметрами, используйте __asm__ вместо asm (см. Альтернативные ключевые слова).
Квалификаторы
volatileНеобязательный квалификатор
volatileне оказывает никакого влияния. Все базовыеasmблоки неявно являются volatile.
Параметры
- AssemblerInstructions
-
Это строковая литерал, которая задаёт код ассемблера. Строка может содержать любые инструкции, распознаваемые ассемблером, включая директивы. GCC не анализирует сами ассемблерные инструкции и не знает, что они означают или даже являются ли они валидными ассемблерными данными.
Вы можете разместить несколько ассемблерных инструкций вместе в одной строке
asm, разделённые символами, обычно используемыми в ассемблерном коде для системы. Комбинация, которая работает в большинстве случаев, это перевод строки, плюс табуляция (записанная как ‘\n\t’). Некоторые ассемблеры допускают использование точки с запятой в качестве разделителя строк. Однако обратите внимание, что в некоторых диалектах ассемблера точка с запятой используется для начала комментария.
Примечания
Использование расширенных asm (см. Расширенный ассемблер) обычно приводит к более компактному, безопасному и более эффективному коду, и в большинстве случаев это лучшее решение, чем базовые asm. Однако существуют две ситуации, когда можно использовать только базовые asm:
- Расширенные
asmоператоры должны находиться внутри функции C, поэтому для написания встроенного ассемблерного языка на уровне файла (вне функций C), необходимо использовать базовыеasm. Вы можете использовать этот метод для вывода ассемблерных директив, определения ассемблерных макросов, которые могут быть вызваны в других частях файла, или написания целых функций на языке ассемблера. - Функции, объявленные с атрибутом
naked, также требуют базовыхasm(см. Атрибуты функций).
Безопасный доступ к данным C и вызов функций из базового asm сложнее, чем может показаться. Для доступа к данным C лучше использовать расширенные asm.
Не ожидайте, что последовательность asm операторов останется идеально последовательной после компиляции. Если определенные инструкции должны оставаться последовательными в выходном коде, поместите их в один многоинструкционный asm оператор. Обратите внимание, что оптимизаторы GCC могут перемещать asm операторы относительно другого кода, включая переходы.
asm операторы не могут выполнять переходы в другие asm операторы. GCC не знает об этих переходах и поэтому не может учитывать их при принятии решений об оптимизации. Переходы из asm в метки C поддерживаются только в расширенных asm.
В определенных обстоятельствах GCC может дублировать (или удалять дубликаты) ваш ассемблерный код при оптимизации. Это может привести к неожиданным ошибкам дублирования символов во время компиляции, если ваш ассемблерный код определяет символы или метки.
Предупреждение: Стандарты C не задают семантику для asm, что делает его потенциальным источником несовместимости между компиляторами. Эти несовместимости могут не выдавать предупреждений/ошибок компилятора.
GCC не анализирует asm’s AssemblerInstructions, что означает, что нет способа сообщить компилятору о том, что происходит внутри них. GCC не имеет доступа к символам в asm и может отбрасывать их как неиспользуемые. Он также не знает о побочных эффектах ассемблерного кода, таких как модификация памяти или регистров. В отличие от некоторых компиляторов, GCC предполагает, что никакие изменения в памяти или регистрах не происходят. Это предположение может измениться в будущей версии.
Чтобы избежать проблем с будущими изменениями семантики и несовместимостями между компиляторами, рассмотрите возможность замены базовых asm расширенными asm. См. Как перейти от базового ассемблера к расширенному для получения информации о том, как выполнить эту конвертацию.
Компилятор копирует ассемблерные инструкции в базовом asm дословно в файл выходного ассемблерного кода, без обработки диалектов или каких-либо операторов ‘%’, которые доступны с расширенными asm. Это приводит к небольшим различиям между базовыми asm строками и расширенными asm шаблонами. Например, для ссылки на регистры можно использовать ‘%eax’ в базовом asm и ‘%%eax’ в расширенном asm.
На таких целевых платформах, как x86, которые поддерживают несколько диалектов ассемблера, все базовые asm блоки используют диалект ассемблера, указанный в командной строке -masm (см. Параметры x86). Базовые asm не предоставляют механизма для предоставления различных ассемблерных строк для разных диалектов.
Вот пример базового asm для i386:
/* Note that this code will not compile with -masm=intel */
#define DebugBreak() asm("int $3")
Далее: Расширенный ассемблер, Назад: Использование ассемблерного языка с C [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-6.5.0/gcc/Basic-Asm.html