You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

手写x86汇编时,是否需主动遵守Linux x86调用约定?

Linux x86调用约定:手写汇编时必须主动遵守
  • 核心结论:调用约定不会自动生效,完全需要程序员手动遵守。你看到clang生成的push/pop操作,就是编译器严格遵守约定的表现,手写汇编时你得自己完成对应的操作。

  • 调用约定的本质是一套软件层面的规则,不是CPU硬件强制的。它明确了函数调用过程中的各项标准:

    • 参数的传递顺序与存储位置(栈或寄存器)
    • 哪些寄存器属于调用者保存:调用函数前,调用者必须自行保存这些寄存器的值,被调用函数可以随意修改它们
    • 哪些寄存器属于被调用者保存:被调用函数必须先保存这些寄存器,返回前恢复原值,不能破坏调用者的状态
    • 栈帧的维护方式、返回值的传递规则等
  • 具体操作要求:

    • 作为调用者(手写汇编调用C函数或其他遵守约定的函数):
      • 提前保存「调用者保存」类寄存器(比如cdecl约定里的EAX、ECX、EDX),避免被调用函数修改后丢失数据
      • 按照约定顺序将参数压栈(比如cdecl是从右到左)
      • 调用结束后按约定清理栈(cdecl由调用者负责,stdcall由被调用者负责)
    • 作为被调用者(手写汇编实现供C调用的函数):
      • 函数开头必须保存「被调用者保存」类寄存器(比如EBX、ESI、EDI、EBP),通常用push指令压栈
      • 函数结束前要通过pop指令恢复这些寄存器的原值,再执行返回操作
      • 需维护好EBP栈帧结构,确保调用者的栈状态不被破坏
  • 你观察到的clang生成的push/pop,要么是调用者在保存自身需要的寄存器,要么是被调用者在履行自身的寄存器保存责任。如果手写汇编时不遵守这些规则,会直接导致栈混乱、寄存器值被意外覆盖、函数调用崩溃等问题。

内容的提问来源于stack exchange,提问作者Tarique

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 04:29:50