How do vararg functions find out the number of arguments in machine code?

后端 未结 4 2103
清酒与你
清酒与你 2020-12-03 11:51

How can variadic functions like printf find out the number of arguments they got?

The amount of arguments obviously isn\'t passed as a (hidden) parameter (s

4条回答
  •  心在旅途
    2020-12-03 12:11

    • The AMD64 System V ABI (Linux, Mac OS X) does pass the number vector (SSE / AVX) varargs in al (the low byte of RAX), unlike any standard IA-32 calling conventions. See also: Why is %eax zeroed before a call to printf?

      But only up to 8 (the max number of registers to use). And IIRC, the ABI allows al to be greater than the actual number of XMM/YMM/ZMM args but it must not be less. So it does not in general always tell you the number of FP args; you can't tell how many more than 8, and al is allowed to overcount.

      It's only usable for performance reasons, to skip saving unneeded vector registers to the "Register Save Area" mentioned in "3.5.7 Variable Argument Lists". For example GCC makes code that tests al!=0 and then dumps XMM0..7 to the stack or nothing. (Or if the function uses VA_ARG with __m256 anywhere, then YMM0..7.)

    • On the C level, there are also other techniques besides parsing the format string as mentioned by others. You could also:

      • pass a sentinel (void *)0 to indicate the last argument like execl does.

        You will want to use the sentinel function attribute to help GCC enforce that at compile time: C warning Missing sentinel in function call

      • pass it as an extra integer argument with the number of varargs

      • use the format function attribute to help GCC enforce format strings of known types like printf or strftime

    Related: How are variable arguments implemented in gcc?

提交回复
热议问题