Most of the time, you will need a tiny bit of non-standard stuff in your compiler to do so.
For example, I don't think there is a portable way to let your compiler use Pascal calling conventions, or to pass information in specific registers or in processor flags.
As an extreme example, in classic Mac OS, you could register a function to be called for line breaking in text input boxes that had the ABI "Parameters are passed to the routine in registers A3, A4, and D0, and output is returned in the Z flag of the Status Register." (https://developer.apple.com/legacy/library/documentation/mac..., page 2-31 gives several other special-cased ABI's in Mac OS)
Browsing that, I also encountered "The routine follows the C calling conventions employed by the THINK C software development environment. Arguments are passed on the stack from right to left, and a result is returned in register D0."
(Aside: that compiler must have treated vararg functions differently)
So, apparently, one cannot even count on C compilers to push arguments from left to right. So, if your ABI says "push X first, then y", I don't think you can portably call that function from C.
So, apparently, one cannot even count on C compilers to push arguments from left to right.
Right-to-left is pretty much the most sensible way to implement variadic functions with a stack-based calling convention - the argument that the function uses to interpret the rest of them must be found at a known location relative to the stack "top", and due to how stacks work, that implies the varying portion has to be pushed first, thus right-to-left.
Maybe if C decided to design things a little differently:
int printf(..., const char *format);
...
printf(5, "There are %d lights.\n");
we would instead have right-to-left being the dominant C calling convention.
For example, I don't think there is a portable way to let your compiler use Pascal calling conventions, or to pass information in specific registers or in processor flags.
As an extreme example, in classic Mac OS, you could register a function to be called for line breaking in text input boxes that had the ABI "Parameters are passed to the routine in registers A3, A4, and D0, and output is returned in the Z flag of the Status Register." (https://developer.apple.com/legacy/library/documentation/mac..., page 2-31 gives several other special-cased ABI's in Mac OS)
Browsing that, I also encountered "The routine follows the C calling conventions employed by the THINK C software development environment. Arguments are passed on the stack from right to left, and a result is returned in register D0."
(Aside: that compiler must have treated vararg functions differently)
So, apparently, one cannot even count on C compilers to push arguments from left to right. So, if your ABI says "push X first, then y", I don't think you can portably call that function from C.