Spec-Zone.ru › GCC 6

6.44.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-6.5.0/gcc/Global-Register-Variables.html

Spec-Zone.ru

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