Spec-Zone.ru › GCC 8

6.45.1 Базовый Asm — Инструкции ассемблера без операндов

Базовое asm утверждение имеет следующий синтаксис:

asm asm-qualifiers ( AssemblerInstructions )

Ключевое слово asm является расширением GNU. При написании кода, который можно скомпилировать с -ansi и различными опциями -std, используйте __asm__ вместо asm (см. Альтернативные ключевые слова).

Квалификаторы

volatile

Необязательный квалификатор volatile не оказывает никакого влияния. Все базовые asm блоки неявно являются volatile.

inline

Если вы используете квалификатор inline, то для целей встраивания размер asm берется как наименьший возможный (см. Размер asm).

Параметры

AssemblerInstructions

Это строковая константа, которая определяет ассемблерный код. Строка может содержать любые инструкции, распознаваемые ассемблером, включая директивы. GCC не анализирует сами ассемблерные инструкции и не знает, что они означают или даже являются ли они допустимым ассемблерным вводом.

Вы можете поместить несколько ассемблерных инструкций вместе в одну строку asm, разделенные символами, обычно используемыми в ассемблерном коде для системы. Комбинация, которая работает в большинстве случаев, — это перевод строки, плюс табуляция (записанная как ‘\n\t’). Некоторые ассемблеры допускают использование точки с запятой в качестве разделителя строк. Однако обратите внимание, что в некоторых диалектах ассемблера точки с запятой используются для начала комментария.

Примечания

Использование расширенного asm (см. Расширенный 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 AssemblerInstructions, что означает, что нет способа сообщить компилятору, что происходит внутри него. GCC не имеет видимости символов в asm и может отбрасывать их как неиспользуемые. Он также не знает о побочных эффектах ассемблерного кода, таких как изменения памяти или регистров. В отличие от некоторых компиляторов, GCC предполагает, что изменения в регистрах общего назначения не происходят. Это предположение может измениться в будущей версии.

Чтобы избежать проблем, связанных с будущими изменениями семантики и проблемами совместимости между компиляторами, рассмотрите возможность замены базового asm на расширенный asm. См. Как перейти от базового asm к расширенному asm для получения информации о том, как выполнить эту конвертацию.

Компилятор копирует ассемблерные инструкции в базовом asm дословно в выходной файл ассемблерного языка, без обработки диалектов или каких-либо операторов ‘%’, доступных с расширенным asm. Это приводит к небольшим различиям между строками базового asm и шаблонами расширенного asm. Например, для ссылки на регистры можно использовать ‘%eax’ в базовом asm и ‘%%eax’ в расширенном asm.

На целевых платформах, таких как x86, которые поддерживают несколько ассемблерных диалектов, все базовые asm блоки используют ассемблерный диалект, указанный опцией командной строки -masm (см. Опции x86). Базовый asm не предоставляет механизма для предоставления разных ассемблерных строк для разных диалектов.

Для базового asm с непустой ассемблерной строкой GCC предполагает, что ассемблерный блок не изменяет регистры общего назначения, но может читать или записывать любые глобально доступные переменные.

Вот пример базового asm для i386:

/* Note that this code will not compile with -masm=intel */
#define DebugBreak() asm("int $3")

Далее: Расширенный Asm, Наверх: Использование ассемблерного языка с C [Оглавление][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/Basic-Asm.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API