Spec-Zone.ru › GCC 10

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

6.47.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) Internals).

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

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

Spec-Zone.ru

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