6.44.2 Указание регистров для локальных переменных
Вы можете определить локальную переменную-регистр со специфицированным регистром следующим образом:
register int *foo asm ("a5"); Здесь a5 — имя регистра, который следует использовать. Обратите внимание, что это тот же синтаксис, что и для определения глобальных переменных-регистров, но для локальной переменной он используется внутри функции.
Естественно, имя регистра зависит от процессора, но это не проблема, так как конкретные регистры чаще всего полезны с явными инструкциями ассемблера (см. Расширенный ассемблер). Оба эти аспекта обычно требуют условной обработки вашего программы в зависимости от типа процессора.
Кроме того, операционные системы на одном типе процессора могут отличаться в способе именования регистров; тогда вам потребуются дополнительные условные проверки. Например, некоторые операционные системы для 68000 называют этот регистр %a5.
Определение такой переменной-регистра не резервирует регистр; он остается доступным для других использований в тех местах, где управление потоком определяет, что значение переменной не активно.
Этот вариант не гарантирует, что GCC сгенерирует код, в котором эта переменная находится в указанном вами регистре постоянно. Вы не можете выполнить явную ссылку на этот регистр в части шаблона инструкции ассемблера оператора asm и предположить, что она всегда ссылается на эту переменную. Однако использование переменной в качестве asm операнда гарантирует, что указанный регистр используется для операнда.
Записи в локальные переменные-регистры могут быть удалены, когда они, по результатам анализа потока данных, оказываются неактуальными. Ссылки на локальные переменные-регистры могут быть удалены, перемещены или упрощены.
Как и в случае с глобальными переменными-регистрами, рекомендуется выбирать регистр, который обычно сохраняется и восстанавливается вызовами функций на вашей машине, чтобы библиотечные функции не уничтожили его. Распространённой ошибкой является инициализация нескольких регистров, подверженных перекрытию вызовом, произвольными выражениями, где вызов функции или библиотечной функции для арифметического оператора перезаписывает значение регистра из предыдущего присваивания, например, r0 ниже:
register int *p1 asm ("r0") = ...;
register int *p2 asm ("r1") = ...; В этих случаях решением является использование временной переменной для каждого произвольного выражения. См. Пример ассемблерного кода с перекрытым регистром.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Local-Reg-Vars.html