logoalt Hacker News

rep_lodsblast Sunday at 2:16 PM2 repliesview on HN

On x86, the RET instruction can add a constant to the stack pointer after popping the return address. Compared to the caller cleaning up the stack, this saves 3 bytes (and about the same number of clock cycles) for every call.

There is nothing wrong with using this calling convention, except for those specific functions that need to have a variable number of arguments - and why not handle those few ones differently instead, unless you're using a braindead compiler / language that doesn't keep track of how functions are declared?


Replies

skissanelast Monday at 12:34 AM

> There is nothing wrong with using this calling convention, except for those specific functions that need to have a variable number of arguments

I think it is a big pity that contemporary mainstream x86[-64] calling conventions (both Windows and the SysV ABI used by Linux-and almost everybody else) don’t pass the argument count in a register for varargs functions. This means there is no generic way for a varargs function to know how many arguments it was called with - some functions use a sentinel value (often NULL), for some one of the arguments contains an embedded DSL you need to parse (e.g. printf and friends). Using obtuse preprocessor magic you can make a macro with the same name as your function which automatically passes its argument count as a parameter-but that is rarely actually done.

OpenVMS calling convention-including the modified version of SysV ABI which the OpenVMS x86-64 port uses-passes the argument count of varargs function calls in a register (eax), which is then available using the va_count macro. I don’t know why Windows/Linux/etc didn’t copy this idea, I wish they had - but it is too late now.

mananaysiemprelast Sunday at 5:37 PM

> There is nothing wrong with using this calling convention

Moreover, it can actually support tail calls between functions of arbitrary (non-vararg) signatures.