C 中的 printf() 使用什么调用约定?

Eme*_*era 1 c x86 assembly variadic-functions calling-convention

因此,我一直在练习使用 CDECL 和 STDCALL 调用约定在 FASMW 中编写简单的子例程,这让我想知道printfC 中的函数将使用什么。

此外,x86 32 位汇编中的函数定义也很棒。如果这还不算过分的话。

Eri*_*hil 7

根据 C 2018 7.1.4 2 和 7.21.6.3 1,printf如果程序将其声明为int printf(const char * restrict format, ...);,则必须工作,因此printf必须使用 C 实现的默认调用约定。

C 实现有可能提供 的多个实现printf,因此提供了指定 的第二个实现的函数或宏#include <stdio.h>的替代声明。然而,必须提供上述主要实现。printfprintf

此外,x86 32 位汇编中的函数定义也很棒。

printf您不太可能找到汇编语言的高质量现代实现,除非通过编译 C 和/或其他语言的实现来获得。实际上,您不太可能在单个例程中找到定义。printf是一个具有许多子部分的复杂例程,并且通常其实现分散在多个例程和源文件中。这个答案这个答案有一些实现的链接。vprintf前者包含到 GNU C 库实现(或其入口点)的链接,这是printf.

  • ISO C 要求强加了另一个约束:传递额外参数是明确定义的行为,例如 `printf("%d\n", 1, 2, 3);` Printf 必须安全地忽略它们,并且表现得像 `printf("% d\n", 1);`。这排除了诸如 STDCALL 之类的被调用者弹出约定。(这对于任何可变参数函数来说都是非常不方便的,因为 `ret imm16` 只适用于立即数。)这就是为什么 Windows C 实现总是对可变参数函数使用像 CDECL 这样的约定,即使它们默认为 STDCALL 或 FASTCALL (32-位版本是 callee-pops),用于具有固定数量参数的函数。 (3认同)