Spec-Zone.ru › GCC 10

Далее: Расширенный Asm — Инструкции ассемблера с операндами выражений C, Вверх: Как использовать язык ассемблера встраиваемого кода на 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")

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

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

Spec-Zone.ru

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