Spec-Zone.ru › GCC 7

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

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

register int *foo asm ("r12");

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

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

Единственное поддерживаемое использование этой функции — указание регистров для операндов входных и выходных данных при вызове Расширенной asm (см. Расширенный ассемблер). Это может потребоваться, если ограничения для конкретной машины не предоставляют достаточного контроля для выбора нужного регистра. Чтобы принудительно поместить операнд в регистр, создайте локальную переменную и укажите имя регистра после объявления переменной. Затем используйте локальную переменную для операнда 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) Internals).

Предыдущий: Глобальные переменные регистров, Верхний уровень: Явные переменные регистров [Содержание][Индекс]

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

Spec-Zone.ru

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