Spec-Zone.ru › GCC 12

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

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

asm asm-qualifiers ( AssemblerInstructions )

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

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

volatile

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

inline

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

Параметры

AssemblerInstructions

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

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

Замечания

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

Чтобы избежать проблем с будущими изменениями семантики и проблемами совместимости между компиляторами, рассмотрите возможность замены базового 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")

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

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

Spec-Zone.ru

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