【问题标题】:Can programming languages have their own calling conventions?编程语言可以有自己的调用约定吗?
【发布时间】:2021-07-09 10:09:52
【问题描述】:

Windows 和 Unix 有自己的calling-conventions for x86-64。但是,如果一种语言需要/从中受益,它是否可以有自己的调用约定供内部使用?例如,Swift / Python(已编译)可能会受益于拥有多个寄存器以从函数返回多个结果(因为这些语言支持)。因此,保留 3 个寄存器(raxrcxrdx)作为其语言调用约定中的返回值,是否会破坏任何内容?导致任何未被注意到的错误,或在任何情况下导致未定义的行为?

另外,如果不需要遵循那个约定,那他们为什么要为用户空间定义调用约定?

【问题讨论】:

  • 当然。例如,Go 有自己的调用约定。
  • 处理器没有呼叫约定警察。
  • 这就像问您是否可以制造奇数尺寸(5.23mm、8.712mm 等)的螺钉和螺栓,而不是使用标准的。当然可以,而且对于某些项目可能有充分的理由这样做,但如果您想与五金店的现成零件进行互操作,则需要构建额外的适配器和配件。
  • 即使是 C 或 C++ 中的内部函数也可以有自定义调用约定。编译器将在调用这些函数时进行调整以最大限度地减少寄存器溢出。只要不从外面叫,就没有问题
  • 更常见的是实现语言有自己的调用约定,至少在过去网络使共享代码(包括二进制文件)变得容易之前。例如同一语言的不同编译器/链接器可能使用不同的约定,至少在默认情况下是这样,因此要进行互操作,您可能需要在 32 位 Windows C 环境中声明具有__stdcall__fastcall 属性/declspec 的原型。跨度>

标签: assembly x86-64 calling-convention


【解决方案1】:

当然,他们可以。剩下的问题将是与 API/操作系统的交互,您必须遵守操作系统的做事方式。

总的来说,重点可能是成本/收益关系。

但对于特殊目的,这是可能的,甚至可能是更好的(否则你为什么还要这样做?)。
此外,还要考虑到对特定于操作系统的事物(例如 red-zone)可能产生的副作用。

【讨论】:

    【解决方案2】:

    调用约定完全由编译器的作者决定。没有任何理由它们符合任何 ISA 供应商记录的约定或任何其他约定。对于已创建约定的 ISA 供应商,它们经常被使用。但是没有要求。看看昔日的 x86。标准的概念是一个相对较新的东西(在编译语言的时间范围内)。

    如果您想创建二进制文件,那么您可以做任何您想做的事情,如果您希望制作可与其他工具链中的二进制文件一起使用的对象/库,那么双方(竞争且可能不相处)都需要使用相同的约定。这通常意味着存在一个占主导地位的工具链,而其他工具链则试图遵循并跟上变化。

    共享运行时库(.dll、.so 等)将使用约定编译二进制文件,如果您希望应用程序能够使用它们,则需要使用该约定调用其中的函数,无论是您用来使用不同约定的 shim,还是您的编译器本机使用相同约定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      相关资源
      最近更新 更多