Spec-Zone.ru › GCC 11

Next: Расширенный Asm — Инструкции ассемблера с операндами выражений C, Up: Как использовать язык ассемблера встраиваемого кода C [Содержание][Индекс]

6.47.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 — Инструкции ассемблера с операндами выражений C) обычно приводит к более компактному, безопасному и эффективному коду, и в большинстве случаев это лучшее решение, чем базовый 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. Например, для ссылки на регистры вы можете использовать ‘%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")

Next: Расширенный Asm — Инструкции ассемблера с операндами выражений C, Up: Как использовать язык ассемблера встраиваемого кода C [Содержание][Индекс]

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

Spec-Zone.ru

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