5 ms·
Suppose you're right and the registers are arbitrary. Then how would foreign function calls work? If you're compiling Rust code that calls into a C library, how
by MichaelBurge 10y ago
Suppose you're right and the registers are arbitrary. Then how would foreign function calls work? If you're compiling Rust code that calls into a C library, how does it know what registers to use?
So the choice of registers cannot be arbitrary, unless the compiler knows the function is only used within an object file.
The registers are predetermined by a convention unless you use the 'static' keyword to signal that the function is only used internally to a module, so the compiler has complete freedom to choose registers.
- pjmlp 10y agoThat is the role of operating system ABI, which definines the calling conventions between the programming languages on the OS.
- makmanalp 10y ago> If you're compiling Rust code that calls into a C library, how does it know what registers to use? Ah, interesting, I figured that the generated object files would just store some metadata on that basically.
- MichaelBurge 10y agoThat can work for statically-linked object files, but what about dynamically linked? You can load one with a function call, get back a function pointer, and invoke it like any other function. Trying to use some metadata would slow down the function call significantly, even if you tried to cache it somewhere.
- userbinator 10y agoThen how would foreign function calls work? If you're compiling Rust code that calls into a C library, how does it know what registers to use? By using information kept with the function, or perhaps even encoded into the function name itself (as already happens when distinguishing between different calling conventions, or in the case of C++ name mangling)? Coming from an Asm background, where there basically is no one "calling convention", and programmers would document which registers (almost always registers, rarely the stack --- and that can make for some great efficiency gains) are for what, I've always wondered why that idea didn't seem to go far.
- deleted 10y ago[deleted]
- masklinn 10y ago> By using information kept with the function How would you do that with dynamically linked code, inspect functions you're calling at runtime before laying out your arguments? > perhaps even encoded into the function name itself That would mean name mangling in C and assembly. > Coming from an Asm background, where there basically is no one "calling convention" Right, because you can lay out memory however you want since you're at the assembly level. Higher-level code (C up) can't do that, so instead you've got standard calling conventions for inter-library call (inside a compilation unit, the compiler is free to use alternate calling conventions since it has complete control over both sides of the callsite, that's also how it can inline calls entirely). > programmers would document which registers (almost always registers, rarely the stack --- and that can make for some great efficiency gains) Some standard CC (though not the old CDECL) also use registers, so far as they can, depending on the arch. The SystemV AMD64 ABI uses 6 x86_64 registers for integer/pointer arguments and 8 SSE registers for FP arguments, with the rest on the stack.
- pmjordan 10y agoWin32 has various different calling conventions, and each function is annotated accordingly in the header files. It's all a bit of a mess, which is presumably why they drastically simplified it in the x64 transition. (And realistically, for all but the most trivial functions, having one convention is probably a highly reasonable default. Trivial functions should probably be made available to the compiler for inlining anyway. Note also that GCC allows you to override the number of arguments passed on the stack via an annotation on 32-bit x86, if you insist.)