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