Spec-Zone.ru › GCC 7

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 не анализирует 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 [Содержание][Индекс]

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

Spec-Zone.ru

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