Чтение регистров в G CC с использованием указателя char - PullRequest
0 голосов
/ 27 мая 2020

Недавно я начал изучать, как использовать встроенную сборку в коде C, и наткнулся на интересную особенность, в которой вы можете указывать регистры для локальных переменных (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local -Register-Variables ).

Эта функция используется следующим образом:

register int *foo asm ("r12");

Затем я начал задаваться вопросом, можно ли вставить указатель char, например

const char d[4] = "r12";
register int *foo asm (d);

, но получил error: expected string literal before ‘d’ (как и ожидалось)

Я могу понять, почему это было бы плохой практикой, но есть ли какой-либо способ добиться аналогичного эффекта, когда я могу использовать указатель char на получить доступ к реестру? Если нет, то есть ли какая-то конкретная причина, по которой это запрещено, помимо потенциальных проблем с безопасностью?

Кроме того, я прочитал этот вопрос StackOverflow: Строковые литералы: указатель против массива символов

Спасибо.

1 Ответ

3 голосов
/ 27 мая 2020

Синтаксис для инициализации переменной будет register char *foo asm ("r12") = d; для указания переменной asm-register на строку. Вы не можете использовать строку переменной времени выполнения в качестве имени регистра; варианты регистров должны быть собраны в машинный код во время компиляции.

Если это то, что вы пытаетесь сделать, вы неправильно понимаете что-то фундаментальное о языке ассемблера и / или о том, как скомпилированные заранее языки компилируются в машинный код. G CC не будет создавать самомодифицирующийся код (и даже если бы он захотел, безопасное выполнение этого потребовало бы повторного выделения регистров, выполненного опережающим оптимизатором) или кода, который повторно выполняет JIT на основе строки .

(В первый раз, когда я посмотрел на ваш вопрос, я не понял, что вы даже пытались сделать, потому что я только рассматривал то, что возможно. Комментарий @FelixG был подсказкой, которую мне нужно было сделать смысл вопроса.)


(Также обратите внимание, что регистры не индексируются; даже в asm вы не можете использовать одну инструкцию для чтения номера регистра, выбранного целым числом в другом регистре. Вы может ветвиться на нем, или хранить все регистры в памяти и индексировать, как функции вариади c делают для своих аргументов входящих регистров.)

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

...