1

A friend of mine sent me an assembly function with a description like this:

Function Foo
Parameters:
EAX -> unsigned 32 bit integer
CL -> unsigned 16 bit integer
RDI -> unsigned 64 bit integer

Now I need to call this function from my C program and I solved the problem by doing this:

asm volatile ("         \n\t\
    mov eax, 0          \n\t\
    mov cl, 1           \n\t\
    mov rdi, 0x120000   \n\t\
    call foo            \n\t\
");

Which works but is a bit ugly and inconvenient. I thought about wrapping this inline asm in a function but I don't like it as a solution. I tried to declare the function as extern:

extern foo(uint32_t eax, uint16_t cl, uint64_t rdi);

And with this line, the compiler does not complain at all but the parameters are all messed up. Is there a way to simplify the calling of this function with extern? If not how do I have to modify the parameters to make it works with this technique?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Delarosa
  • 11
  • 1
  • 1
    Change parameter passing to conform to whatever ABI you are using. On linux that would be the sysv one. Pass your 3 arguments in `rdi`, `rsi`, `rdx`. See for example [wikipedia](https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI) – Jester Dec 24 '20 at 22:09
  • @Jester Ok, since I'm using gcc I'll switch to these three registers that you've listed. If you post this comment as a answer I'll check it as correct – Delarosa Dec 24 '20 at 22:20
  • 1
    Note that you cannot overwrite random registers in an `asm` statement. The compiler expects that all register's contents will be preserved by inline assembly. – fuz Dec 24 '20 at 23:07
  • 1
    @Delarosa if you overwrite registers in inline assembly be sure to include them in the clobbers list. See more at https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html – Noah Dec 24 '20 at 23:09
  • 1
    `CL` is an 8-bit register, not 16-bit. The corresponding 16-bit register is `CX`. You should check with your friend to clarify what was intended. – Nate Eldredge Dec 24 '20 at 23:34
  • 100% agreed with Jester: if you want to call from C, write your asm to follow a standard calling convention that the compiler already knows how to call. x86-64 System V is nice. Do *not* use inline asm, especially not in 64-bit mode; it's a massive pain and very hard to do safely, and causes a lot of inefficiency. (e.g. [Calling printf in extended inline ASM](https://stackoverflow.com/a/37503773)) Compilers are good at making function calls based on a prototype. – Peter Cordes Dec 24 '20 at 23:44

0 Answers0