views:

41

answers:

1

Without getting into specifics, say I need to make use of a non-standard calling convention from C code. Functions that use this convention may return multiple values on the stack. It would be simple to put each function in a wrapper that uses inline assembly to make the call, sending output via pointer parameters given to the wrapper. Unfortunately, this solution doesn't generalise well, and I need something that works in the general case. Should I just give up and use macros to encapsulate wrapping, or is there a more general way to write, say, a variadic invoke function that handles the dirty work of managing the stack?

+3  A: 

Whichever approach you choose, you'll need to write the wrapper in assembly. There is no way to fiddle with the stack from C. I do like your idea of writing a single invoke wrapper (in asm) that does all the dirty work, and then wrapping that with C.

R..
If I write `invoke` in C using inline assembly, is it safe to interleave the `asm` with calls to `va_arg`, as long as I'm careful not to clobber the stack? It seems as though `va_arg` is just adjusting a `va_list` pointer based on the `sizeof` its argument.
Jon Purdy
With a good inline asm system (note: this is totally outside the C standard), I think it should be fairly safe, but I'm not sure why you'd want to split the asm up into multiple `asm` blocks. By the way, a cleaner alternative might be to write `invoke` in pure asm, not as a C function with asm, so you can reuse the stack directly for the foreign call without fooling with `va_arg`.
R..
Oh, right. I can just use `cdecl`. For some reason I was thinking `invoke` would have to be calling-convention-agnostic, which isn't actually the case. Thanks!
Jon Purdy
Once you're writing asm (not to mention interfacing with existing binary code), I think you can pretty safely assume the standard calling convention for the cpu family you're targetting. :-)
R..