Spec-Zone.ru › GCC 7

6.45.5.1 Определение глобальных регистровых переменных

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

register int *foo asm ("r12");

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

Регистры являются ограниченным ресурсом на большинстве систем, и предоставление компилятору управления их использованием, как правило, приводит к лучшему коду. Однако в особых случаях может быть целесообразно зарезервировать некоторые глобально. Например, это может быть полезно в программах, таких как интерпретаторы языков программирования, имеющие несколько глобальных переменных, к которым часто обращаются.

После определения глобальной регистровой переменной для текущей единицы компиляции:

  • Регистр полностью резервируется для этого использования и не будет выделен для других целей.
  • Регистр не сохраняется и не восстанавливается никакими функциями.
  • Записи в этот регистр никогда не удаляются, даже если они кажутся мёртвыми, но ссылки могут быть удалены, перемещены или упрощены.

Обратите внимание, что эти пункты только применяются к коду, который компилируется с определением. Поведение кода, который просто связан (например, код из библиотек), не изменяется.

Если вы хотите перекомпилировать исходные файлы, которые фактически не используют вашу глобальную регистровую переменную, чтобы они не использовали указанный регистр для других целей, вам не нужно добавлять объявление глобальной регистровой переменной в их исходный код. Достаточно указать опцию компилятора -ffixed-reg (см. Опции генерации кода) для резервирования регистра.

Объявление переменной

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

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

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

Использование переменной

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

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

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

В конечном счёте, может появиться способ попросить компилятор автоматически выбрать регистр, но сначала нужно понять, как он должен выбирать и как позволить вам управлять выбором. Очевидного решения нет.

Далее: Локальные регистровые переменные, Вверх: Явные регистровые переменные [Содержание][Индекс]

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

Spec-Zone.ru

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