为什么并非所有 C 程序都使用调用约定

Joe*_*Joe 1 c winapi calling-convention

我是编程新手,在阅读 Charles Petzold 的书Programming Windows 时,我偶然发现了 WINAPI(实际上,除了返回类型之外,函数名称之前还存在另一个词让我感到惊讶),发现它是一个调用约定,并且是最好的我的理解是函数如何将变量压入堆栈并获取返回值的一种方式,我想知道为什么我们不在每个 C 程序中都使用它们?它们只是操作系统编程所独有的吗?

Sha*_*ger 6

调用约定通常与编译器、体系结构和(在使用系统运行时库时)操作系统相关;它们根本不是 C 标准的一部分。在大多数情况下,给定架构/编译器/操作系统组合只有一种调用约定,因此您无需考虑;它只使用操作系统支持的唯一约定。

在最近的历史中,它非常重要的一个地方是在 32 位 x86 系统上,尤其是在 Windows 上。x86 的通用寄存器很少,所以只有少数可用,比典型函数可能需要的参数少,并且使用它们进行参数传递意味着您经常需要将它们曾经包含的任何内容推送到堆栈中,所以在调用约定中有很多权衡(在寄存器中传递参数更快,但前提是调用者可以节省寄存器或至少不会被迫过度溢出到堆栈),而 Windows 与“我们将在不同的场景中使用它们”。

在 x86-64(寄存器匮乏的情况下)和非 x86 架构(通常有足够的寄存器)上的现代用法中,大多数编译器/操作系统坚持使用单一的通用调用约定,因此,您再次不需要请注意。这是一种好奇心,除非您在汇编中手写整个函数,否则您不需要亲自关注。