Spec-Zone.ru › GCC 9

6.47.1 Основные инструкции ассемблера без операндов

У простого 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. Вы можете использовать эту технику для вывода директивы ассемблера, определения макросов языка ассемблера, которые можно вызывать в других частях файла, или написания целых функций на языке ассемблера. В операторах базового asm вне функций нельзя использовать квалификаторы.
  • Функции, объявленные с атрибутом naked, также требуют базового asm (см. Атрибуты функций).

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

Не ожидайте, что последовательность asm операторов останется идеально последовательной после компиляции. Если определённые инструкции должны оставаться последовательными в выходном коде, поместите их в один оператор asm с несколькими инструкциями. Обратите внимание, что оптимизаторы GCC могут перемещать asm операторы относительно другого кода, в том числе через переходы.

Операторы asm не могут выполнять переходы в другие asm операторы. GCC не знает об этих переходах и, следовательно, не может учитывать их при принятии решений об оптимизации. Переходы из asm в метки C поддерживаются только в расширенных asm операторах.

В определённых обстоятельствах GCC может дублировать (или удалять дубликаты) ваш ассемблерный код при оптимизации. Это может привести к неожиданным ошибкам дублирования символов во время компиляции, если ваш ассемблерный код определяет символы или метки.

Предупреждение: Стандарты C не определяют семантику asm, что делает её потенциальным источником несовместимости между компиляторами. Эта несовместимость может не генерировать предупреждений/ошибок компилятора.

GCC не анализирует AssemblerInstructions базового asm, что означает, что нет способа сообщить компилятору, что происходит внутри него. GCC не видит символы в asm и может отклонить их как неиспользуемые. Он также не знает о побочных эффектах ассемблерного кода, таких как изменения памяти или регистров. В отличие от некоторых компиляторов, GCC предполагает, что не происходит изменений в регистрах общего назначения. Это предположение может измениться в будущей версии.

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

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

Например, для обращения к регистрам в базовом asm можно использовать ‘%eax’, а в расширенном asm — ‘%%eax’.

На таких платформах, как 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-9.5.0/gcc/Basic-Asm.html

Spec-Zone.ru

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