news 2026/9/25 14:52:48

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

作者头像

张小明

前端开发工程师

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)大小的参数通过寄存器传递(通常是ECX和EDX)。
    • 剩余参数从右到左压栈。
  • 栈清理方:被调用者(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右→左Caller否是C 函数(x86)
stdcall右→左Callee否否Windows API
fastcall右→左 + 寄存器Callee是(前两个)否性能敏感函数
thiscall右→左Callee*ECX (this)否/是C++ 非静态成员函数
System V x64寄存器优先Caller是(最多6个整型)是Linux/macOS 64位程序

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

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

内容创作者在生成式AI搜索时代的生存与繁荣策略

引言:内容价值的重新定义当生成式AI能够瞬间综合全网信息生成看似完美的答案时,许多内容创作者面临生存危机:如果用户不再访问原始来源,创作者如何获得认可和回报?然而,危机中蕴含转机——AI无法替代人类的…

作者头像 李华
网站建设 2026/9/2 16:12:06

嵌入式知识篇---74LS192

1. 一句话概括它是什么74LS192 是一个“可逆、可预置的十进制同步计数器”。 听起来很复杂?别怕,我们拆开看:计数器:它会自动数数(0,1,2,3...)。十进制:它从0数到9,然后归零&#xf…

作者头像 李华
网站建设 2026/9/24 3:40:11

Java开发裸辞狂刷两个月面试题,终于拿到某独角兽offer,分享还愿!

前言 今天给大家分享下我整理的Java架构面试专题及答案,其中大部分都是大企业面试常问的面试题,可以对照这查漏补缺,当然了,这里所列的肯定不可能覆盖全部方式。 很多Java开发者面试之前,可能没有较长的工作时间或者…

作者头像 李华
网站建设 2026/9/18 19:52:31

12款常见降ai率工具大汇总(含免费降ai率版)

“论文降ai”是2025年毕业生面临的新挑战。它指的是一个过程:我们使用专门的降ai工具,去修改另一篇由AI(如GPT、Kimi)生成的文本,目的是为了“消除AI痕迹”,让文章看起来更像人类原创。 这个过程通常利用深…

作者头像 李华
网站建设 2026/9/22 12:51:28

2款常见降ai率工具大汇总(含免费降ai率版,还有免费ai查重!)

“论文降ai”是2025年毕业生面临的新挑战。它指的是一个过程:我们使用专门的降ai工具,去修改另一篇由AI(如GPT、Kimi)生成的文本,目的是为了“消除AI痕迹”,让文章看起来更像人类原创。 这个过程通常利用深…

作者头像 李华
网站建设 2026/9/25 10:05:37

12款常见降ai率工具大汇总(含免费降ai率版,5个有效方法推荐)

“论文降ai”是2025年毕业生面临的新挑战。它指的是一个过程:我们使用专门的降ai工具,去修改另一篇由AI(如GPT、Kimi)生成的文本,目的是为了“消除AI痕迹”,让文章看起来更像人类原创。 这个过程通常利用深…

作者头像 李华