Inserting a pointer into eax and ebx registers in GCC

I need to insert a pointer into EAX and the other into the EBX register. At first I solved this with:

register int eax asm("eax"); register int ebx asm("ebx"); int main() { eax = ptr1; ebx = ptr2; } 

Which worked like a charm. However, when I added this to another code, I got strange errors stating that gcc could not find the register to spill in the AREG class, in a completely unrelated part of the code. I googled, and it turned out that this is actually a bug in gcc -.-. So, I need another way to insert two pointers into the eax and ebx registers. Does anyone have any ideas?

Edit:

As people ask what I'm trying to achieve here, I thought I would explain a little.

I need to change eax and ebx for some assembler code that I am trying to run in my program. I need to execute this assembler code and give a pointer to a parameter through the eax and ebx registers. I execute the assembler code by clicking the pointer to it in ebx and calling ebx. When I do not call the register, globally, but locally, the assembly code crashes. If I call it globally, I get this strange error at the end of a random function. When I delete these functions, it throws the same error into another random function. Until my functions run out, then it works, but then I miss the rest of the code: P

+6
source share
2 answers

If you have (built-in) assembler code that requires certain parameters in EAX / EBX , the way to do this in gcc is to use the following:

 __asm__("transmogrify %0, %1\n" : "+a"(val_for_eax), "+b"(val_for_ebx)); 

This exploits the fact that gcc calls the built-in build constraints that tell the compiler that the build code - whatever it is - expects val_for_eax / val_for_ebx in EAX / EBX (which is a / b ), and also return potentially modified versions of these variables (and + ) to these registers.

In addition, the actual code inside the asm() operator does not matter for the compiler - it will need / need to know where the parameters %0 and %1 live. In the above example, due to the transmogrify that does not exist in the current x86 instruction set, assembly failed to start; just replace it with something valid.

An explanation of why gcc behaves this way and what exactly you can say is in the GCC manual:

You can specify a specific register for the variable, but because of how gcc / works, how the built-in assembly is implemented in gcc, therefore it does not mean (!), The register from now on is reserved (out of scope) for gcc for use in its own purposes. This can only be achieved with the help of restrictions for a separate asm() block - the restrictions tell gcc what to write to these registers before the actual assembly code is placed and what to read after them.

+5
source

Because the eax register is needed everywhere in the actual program of your architecture, your strategy cannot work with global variables that are bound to specific registers. Do not do this by reserving a register worldwide, this is not a good idea.

Place the variables bound to the registers in a specific function, as close as possible to their use.

+4
source

Source: https://habr.com/ru/post/945839/


All Articles