0

I have recently started learning how to use the inline assembly in C Code and came across an interesting feature where you can specify registers for local variables (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables).

The usage of this feature is as follows:

register int *foo asm ("r12");

Then I started to wonder whether it was possible to insert a char pointer such as

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

but got the error: expected string literal before ā€˜d’ (as expected)

I can understand why this would be a bad practice, but is there any possible way to achieve a similar effect where I can use a char pointer to access the register? If not, is there any particular reason why this is not allowed besides the potential security issues?

Additionally, I read this StackOverflow question: String literals: pointer vs. char array

Thank you.

Jay
  • 373
  • 1
  • 10
  • 4
    According to the documentation, `register int *foo asm ("r12");` apparently tells the compiler that it should use register `r12` to store the variable `foo`, so it affects the assembler code emitted by the compiler. On the other hand, `register int *foo asm (d);` would mean "store the variable foo in a specific register which isn't known at compile time", and that seems pretty impossible to me. – Felix G May 27 '20 at 09:42

1 Answers1

3

The syntax to initialize the variable would be register char *foo asm ("r12") = d; to point an asm-register variable at a string. You can't use a runtime-variable string as the register name; register choices have to get assembled into machine code at compile time.

If that's what you're trying to do, you're misunderstanding something fundamental about assembly language and/or how ahead-of-time compiled languages compile into machine code. GCC won't make self-modifying code (and even if it wanted to, doing that safely would require redoing register allocation done by the ahead-of-time optimizer), or code that re-JITs itself based on a string.

(The first time I looked at your question, I didn't understand what you were even trying to do, because I was only considering things that are possible. @FelixG's comment was the clue I needed to make sense of the question.)


(Also note that registers aren't indexable; even in asm you can't use a single instruction to read a register number selected by an integer in another register. You could branch on it, or store all the registers in memory and index that like variadic functions do for their incoming register args.)

And if you do want a compile-time constant string literal, just use it with the normal syntax. Use a CPP macro if you want the same string to initialize a char array.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847