Reading a register value into a C variable [duplicate] Reading a register value into a C variable [duplicate] c c

Reading a register value into a C variable [duplicate]


Editor's note: this way of using a local register-asm variable is now documented by GCC as "not supported". It still usually happens to work on GCC, but breaks with clang. (This wording in the documentation was added after this answer was posted, I think.)

The global fixed-register variable version has a large performance cost for 32-bit x86, which only has 7 GP-integer registers (not counting the stack pointer). This would reduce that to 6. Only consider this if you have a global variable that all of your code uses heavily.


Going in a different direction than other answers so far, since I'm not sure what you want.

GCC Manual § 5.40 Variables in Specified Registers

register int *foo asm ("a5");

Here a5 is the name of the register which should be used…

Naturally the register name is cpu-dependent, but this is not a problem, since specific registers are most often useful with explicit assembler instructions (see Extended Asm). Both of these things generally require that you conditionalize your program according to cpu type.

Defining such a register variable does not reserve the register; it remains available for other uses in places where flow control determines the variable's value is not live.

GCC Manual § 3.18 Options for Code Generation Conventions

-ffixed-reg

Treat the register named reg as a fixed register; generated code should never refer to it (except perhaps as a stack pointer, frame pointer or in some other fixed role).

This can replicate Richard's answer in a simpler way,

int main() {    register int i asm("ebx");    return i + 1;}

although this is rather meaningless, as you have no idea what's in the ebx register.

If you combined these two, compiling this with gcc -ffixed-ebx,

#include <stdio.h>register int counter asm("ebx");void check(int n) {    if (!(n % 2 && n % 3 && n % 5)) counter++;}int main() {    int i;    counter = 0;    for (i = 1; i <= 100; i++) check(i);    printf("%d Hamming numbers between 1 and 100\n", counter);    return 0;}

you can ensure that a C variable always uses resides in a register for speedy access and also will not get clobbered by other generated code. (Handily, ebx is callee-save under usual x86 calling conventions, so even if it gets clobbered by calls to other functions compiled without -ffixed-*, it should get restored too.)

On the other hand, this definitely isn't portable, and usually isn't a performance benefit either, as you're restricting the compiler's freedom.


Here is a way to get ebx:

int main(){    int i;    asm("\t movl %%ebx,%0" : "=r"(i));    return i + 1;}

The result:

main:    subl    $4, %esp    #APP             movl %ebx,%eax    #NO_APP    incl    %eax    addl    $4, %esp    ret


Edit:

The "=r"(i) is an output constraint, telling the compiler that the first output (%0) is a register that should be placed in the variable "i". At this optimization level (-O5) the variable i never gets stored to memory, but is held in the eax register, which also happens to be the return value register.


I don't know about gcc, but in VS this is how:

int data = 0;   __asm{    mov ebx, 30    mov data, ebx}cout<<data;

Essentially, I moved the data in ebx to your variable data.