I'm trying to write code to read from a register, and this is what I have so far:
unsigned int readEBX(void) {
register unsigned int reg asm("ebx");
return reg;
}
The function appears to be working, but it compiles to something strange:
readEBX():
mov eax, ebx
push ebx
pop ebx
ret
Why should this push-then-pop ebx? Doesn't this do nothing? When I replace ebx
for another register (say eax
or ecx
), then it produces saner code (just a ret
and a mov eax, ecx; ret
respectively).
See this example Godbolt result.
Since you are explicitly telling the compiler that you are interested in the register, he tries to be smart. Since you want to observe the register, don't tell the compiler, so he can't mess around.
This works for me (modulo the order of the mov
operation)
unsigned int readEBX(void) {
register unsigned int ret __asm__("eax");
__asm__ volatile("mov %%ebx, %0" : "=r"(ret));
return ret;
}
It just ensures that ret
uses a different register, so there is no conflict.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With