I'm trying to make some things with GCC Inline Assembly, in this case, make a Syscall, but I want to force use of 64bit registers (rax, rdi, rsi, ...) instead of 32bit ones (eax, edi, ...), but I tried a lot of ways, and nothing.
void syscall(uint64_t arg1, uint64_t arg2) {
// arg1 -> rax arg2 -> rdi
__asm__("syscall" : : "a" (arg1), "D" (arg2));
}
When I compile that I get:
mov eax, 60
syscall
I'm in a function, so "edi" is being get from arguments, but like you can see is "eax", I want to use rax.
How can I force 64bit registers instead of 32bit ones?
The __asm keyword invokes the inline assembler and can appear wherever a C or C++ statement is legal. It cannot appear by itself. It must be followed by an assembly instruction, a group of instructions enclosed in braces, or, at the very least, an empty pair of braces.
The asm statement allows you to include assembly instructions directly within C code. This may help you to maximize performance in time-sensitive code or to access assembly instructions that are not readily available to C programs. Note that extended asm statements must be inside a function.
R just stands for "register". The AMD64 ISA extension added 8 additional general-purpose registers, named R8 through R15 . The 64-bit extended versions of the original 8 registers had an R prefix added to them for symmetry. E stands for "extended" or "enhanced".
General-purpose registers (64-bit naming conventions)Edit 64-bit x86 adds 8 more general-purpose registers, named R8, R9, R10 and so on up to R15. R8–R15 are the new 64-bit registers. R8D–R15D are the lowermost 32 bits of each register. R8W–R15W are the lowermost 16 bits of each register.
This actually sets the RAX register to 60:
mov eax, 60
Writing to EAX always clears the upper 32-bit half of the 64-bit register. This is not like AH and AL, where writes preserve the rest of the register.
If you absolutely want a move to RAX, you need to use something like this:
static inline __attribute__ ((always_inline)) void
syscall(uint64_t arg1, uint64_t arg2)
{
__asm__("mov rax, %0; syscall" : : "i" (arg1), "D" (arg2) : "rax");
}
Note that gas
will still assemble this as a 32-bit immediate move.
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