Spec-Zone.ru › GCC 14

6.48.5.2 Указание регистров для локальных переменных

Вы можете определить локальную переменную регистра и связать её со специфицированным регистром следующим образом:

register int *foo asm ("r12");

Здесь r12 — имя регистра, которое должно использоваться. Обратите внимание, что это тот же синтаксис, что и для определения глобальных переменных регистра, но для локальной переменной объявление находится внутри функции. Ключевое слово register обязательно и не может быть объединено с static. Имя регистра должно быть допустимым именем регистра для целевой платформы.

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

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

Единственное поддерживаемое использование этой функции — указание регистров для операндов ввода и вывода при вызове расширенного asm (см. Расширенное ассемблерное программирование — ассемблерные инструкции с операндами выражений C). Это может потребоваться, если ограничения для конкретной машины не обеспечивают достаточного контроля для выбора желаемого регистра. Для принудительного помещения операнда в регистр создайте локальную переменную и укажите имя регистра после объявления переменной. Затем используйте локальную переменную для операнда asm и укажите любую буквенную метку ограничения, соответствующую регистру:

register int *p1 asm ("r0") = …;
register int *p2 asm ("r1") = …;
register int *result asm ("r0");
asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));

Предупреждение: В приведенном выше примере имейте в виду, что регистр (например, r0) может быть уничтожен вызовом последующего кода, включая вызовы функций и библиотечных вызовов для арифметических операторов над другими переменными (например, инициализация p2). В этом случае используйте временные переменные для выражений между присваиваниями регистров:

int t1 = …;
register int *p1 asm ("r0") = …;
register int *p2 asm ("r1") = t1;
register int *result asm ("r0");
asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));

Определение переменной регистра не резервирует регистр. За исключением вызова расширенного asm, содержимое указанного регистра не гарантируется. По этой причине следующие использования явно не поддерживаются. Если они кажутся работающими, это просто случайность и они могут перестать работать должным образом из-за (по-видимому) не связанных изменений в окружающем коде или даже незначительных изменений в оптимизации будущей версии gcc:

  • Передача параметров в или из базового asm
  • Передача параметров в или из расширенного asm без использования операндов ввода или вывода.
  • Передача параметров в или из процедур, написанных на ассемблере (или других языках), использующих нестандартные соглашения о вызовах.

Некоторые разработчики используют локальные переменные регистров в попытке улучшить распределение регистров gcc, особенно в больших функциях. В этом случае имя регистра по сути является подсказкой для распределителя регистров. Хотя в некоторых случаях это может генерировать лучший код, улучшения зависят от произвола распределителя/оптимизаторов. Поскольку нет гарантий, что ваши улучшения не будут потеряны, такое использование локальных переменных регистров не рекомендуется.

На платформе MIPS есть связанное использование локальных переменных регистров с немного другими характеристиками (см. Определение особенностей сопроцессоров для MIPS-целей в документации по внутреннему устройству компилятора GNU Compiler Collection (GCC)).

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Local-Register-Variables.html

Spec-Zone.ru

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