news 2026/4/17 21:08:03

过程调用的代码流程涉及多个关键步骤,确保程序能正确传递参数、执行被调用函数并安全返回

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
过程调用的代码流程涉及多个关键步骤,确保程序能正确传递参数、执行被调用函数并安全返回

过程调用的代码流程涉及多个关键步骤,确保程序能正确传递参数、执行被调用函数并安全返回。其典型流程如下:

  1. 参数传递与调用准备(Caller 侧)

    • 计算并压入实际参数到运行时栈。
    • 保存当前栈指针(SP),用于维护调用者栈帧。
    • 记录参数个数(某些语言或调用约定中需要)。
    • 将返回地址(当前指令的下一条)压栈或存入特定寄存器。
    • 执行JSR(Jump to Subroutine)指令跳转到被调用过程。
  2. 进入被调用过程(Callee 侧)

    • 保存旧的栈基址指针(通常称为 FP 或 BP)。
    • 建立新的栈帧:设置新的 SP 和 FP,构成活动记录(Activation Record)。
    • 分配局部变量所需空间。
    • 可选:保存某些寄存器内容(如临时变量使用的寄存器)。
  3. 执行过程体

    • 执行函数内部语句,可能包括表达式计算、控制流、递归调用等。
    • 使用中间代码(如四元式)进行表示和优化。
  4. 过程返回(Return)

    • 将返回值(如有)存入约定位置(寄存器或栈)。
    • 恢复调用者的栈指针 SP 和基址指针 FP。
    • 获取返回地址并跳转回调用点。
    • 清理栈中参数(由调用者或被调用者完成,取决于调用约定)。

在编译过程中,中间代码优化目标代码生成是后端的关键阶段:

  • 中间代码优化

    • 输入是中间表示(如四元式(op, arg1, arg2, result))。
    • 进行等价变换以提升效率,例如常量折叠、公共子表达式消除、循环不变代码外提、死代码删除等。
    • 目标是在不改变程序语义的前提下减少运行时间和空间开销。
  • 目标代码生成

    • 由代码生成器将优化后的中间代码转换为具体机器的汇编或机器码。
    • 需处理寄存器分配、指令选择、寻址模式匹配等问题。
    • 四元式结构因其接近三地址码,便于映射到目标指令。
      常见的过程调用约定(Calling Convention)定义了函数调用时参数如何传递、栈由谁清理、哪些寄存器需保存等规则。不同平台和编译器使用不同的调用约定,尤其在C/C++中较为显著。以下是几种典型的调用约定及其在参数清理寄存器使用上的主要区别:

1.cdecl(C Declaration)

  • 平台/语言:x86 架构下 GCC 和 MSVC 默认的 C 语言调用约定。
  • 参数传递顺序:从右到左压入栈。
  • 栈清理方调用者(Caller)负责清理栈空间。
  • 寄存器使用
    • EAX,ECX,EDX:调用者保存(caller-saved),被调用函数可自由使用。
    • 其他通用寄存器(如EBX,ESI,EDI)为被调用者保存(callee-saved),若使用需先压栈。
  • 用途:支持可变参数函数(如printf),因为只有调用者知道传了多少参数。

2.stdcall(Standard Call)

  • 平台:Windows API 常用。
  • 参数传递顺序:从右到左压栈。
  • 栈清理方被调用者(Callee)ret n指令中自动弹出参数。
  • 寄存器使用
    • 类似 cdecl,EAX,ECX,EDX为 caller-saved。
    • 其余为 callee-saved。
  • 限制:不适用于变参函数(被调用者无法预知参数个数)。

3.fastcall

  • 目的:提高性能,尽可能通过寄存器传参。
  • 参数传递方式
    • 前两个双字(DWORD)大小的参数通过寄存器传递(通常是ECXEDX)。
    • 剩余参数从右到左压栈。
  • 栈清理方被调用者(Callee)清理栈上参数部分。
  • 寄存器使用
    • ECX,EDX用于传参,属于 callee-saved 的一部分。
    • EAX,EDX也常用于返回值(EAX返回整型,EDX:EAX返回64位值)。
  • 优点:减少内存访问,提升速度。

4.thiscall(C++ 成员函数专用)

  • 平台:Microsoft Visual C++ 使用。
  • 隐含参数this:通过寄存器(ECX)传递。
  • 参数传递:其余参数从右到左压栈。
  • 栈清理方:对于固定参数,由被调用者清理;变参则由调用者清理。
  • 仅用于类成员函数调用

5.System V AMD64 ABI(Unix-like 系统 x86-64)

  • 主流标准:Linux、macOS 等 64 位系统默认。
  • 参数传递
    • 前六个整型/指针参数依次使用寄存器:RDI,RSI,RDX,RCX,R8,R9
    • 前八个浮点参数使用XMM0–XMM7
    • 超出部分通过栈传递。
  • 栈清理方调用者清理栈。
  • 寄存器分类
    • caller-saved:RAX,RCX,RDX,R8–R11
    • callee-saved:RBX,RBP,R12–R15,RSP

总结对比表:

调用约定参数传递顺序栈清理方寄存器传参支持变参典型用途
cdecl右→左CallerC 函数(x86)
stdcall右→左CalleeWindows API
fastcall右→左 + 寄存器Callee是(前两个)性能敏感函数
thiscall右→左Callee*ECX (this)否/是C++ 非静态成员函数
System V x64寄存器优先Caller是(最多6个整型)Linux/macOS 64位程序

*注:thiscall 的清理策略依实现而定。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 19:37:46

嵌入式知识篇---74LS48

1. 一句话概括它是什么 74LS48 是一位“翻译官”。 它的工作是把你(或单片机)能看懂的数字密码,翻译成7段数码管能看懂的点亮指令。 你可以把它想象成一个专门为数码管服务的“秘书”。 2. 它解决了什么问题?(为什么…

作者头像 李华
网站建设 2026/4/18 8:06:06

数字员工是什么?熊猫智汇在AI销售工具中的独特优势是什么?

数字员工通过自动化外呼功能,显著优化了企业的业务流程,降低了运营成本并提升了工作效率。这种AI销售工具能够快速处理多个客户沟通,无需人工干预,大幅度减少了传统销售模式中时间的浪费。以AI销冠系统为例,它实时监控…

作者头像 李华
网站建设 2026/4/18 5:35:42

基于Springboot校园悬赏任务服务平台【附源码+文档】

💕💕作者: 米罗学长 💕💕个人简介:混迹java圈十余年,精通Java、小程序、数据库等。 💕💕各类成品Java毕设 。javaweb,ssm,springboot等项目&#…

作者头像 李华
网站建设 2026/4/18 7:41:11

当1200 PLC遇上质子膜压机:一个工控项目的实战拆解

西门子plc,西门子1200系列 西门子自动贴合机 伺服力矩控制,真空腔体控制,加热烘烤控制,配方功能,等 西门子1200 质子膜压机项目,包含上下料程序案例 1、梯形图SCL混合编程; 2、两个S7-1200主从站…

作者头像 李华
网站建设 2026/4/18 5:17:32

昆仑 MCGS 与台达 B2 伺服通过 Modbus RTU 通讯控制教程

昆仑mcgs 通讯控制台达B2伺服采用modbus rtu方式,昆仑屏直接控制台达b2伺服的正反转,停止及速度设定,简单好上手,a2 伺服也可以用,内容包含程序,教程,接线及参数设置最近在搞自动化控制这块&…

作者头像 李华