跟我学C++中级篇——函数调用的本质

news2024/11/27 8:32:58

一、进程的执行过程

正常的情况下,程序会被计算机从硬盘加载到内存中,然后跳转到主入口函数进行执行。依次按照逻辑对相关的模块进行加载调用。其中,最常用的就是调用一个函数,可以说,函数是C/C++程序中的一个重要的基础单元。

二、进程的内存布局

进程中是如何描述加载的程序的分布呢?这其实就是代码或者说程序在内存中的布局,它直接决定着整个计算机对程序的处理机制。前面已经学习过,在操作系统中,一般会把内存分成两大块,即内核空间和用户空间。当然,在内核空间中又会划分成若干个空间布局,这里不做详细的赘述,有兴趣可以自行查找相关书籍资料。
而在对应的应用程序的内存布局中,主要分以下几部分,C语言:
1、堆:动态分配的内存区域,需要手动分配和释放(诸如malloc和free等)
2、栈:用于存储局部变量、函数参数、返回地址等。由操作系统自动管理
3、全局/静态存储区:存储全局变量和静态变量。
4、常量存储区:存储C风格的常量字符串,程序运行中不可更改
5、代码段:存储可执行代码
C++语言:
1、栈:如C中的栈
2、堆:动态分配的内存,不过c++的堆由new和delete负责管理
3、自由存储区: 这是c++不同于C之处。其由malloc()/calloc()/realloc()分配空间,由free()释放。对应C的堆机制
4、全局区/静态区:全局变量和静态变量存放区,程序一经编译好,该区域便存在
5、常量存储区:用来存储不能修改的常量
不过从根本上讲,不管C或C++,程序的内存布局只有BSS段、data段、text段三段组成。只不过在不同的区域不同的语言可能存储的数据有所不同。在不同的资料中,可能对内存的布局讲述略有不同,比如有的还有内存映射区,用来处理库、文件或其它情况的内存映射等等。但通过仔细分析后可以发现,其实它们讲的都是一个基本的内容,只是叫法或者细分的情况有所不同(或者说分析的角度不同)。这个请大家注意。

三、函数和函数调用

在最初学习C/C++语言时,学习了什么是函数。函数是一段可重复使用的代码,本质就是一个模块的入口地址,所以函数又可以称为子程序。而函数既然是可重用的,就必须是可以反复调用的。那么,函数的调用其实就是一个寻址的过程。即找到函数的地址并将相关参数带入到可执行地址。这就涉及到了在汇编语言和操作系统中学过的段页式管理对地址的管理和寻址过程。
同时需要提醒大家的是,32位和64位操作系统对此的处理又有所不同(虽然X64兼容段页式寻址,但正常情况已经忽略了段),切记。

四、函数的调用约定

在前面学习32位操作系统时,特别是学习Windows平台时,在编写动态库时,要求提供导出函数的调用约定,有几种情况比如C形式的(_cdecl),标准形式的(__stdcall),快速调用(__fastcall)等等。这种约定的作用,最主要的是处理函数的参数传递的顺序以及栈的管理维护方式和导出函数的名字的策略。这其实就和不同的国家的人约定要以哪种语言来确定合同的书写规范一样。
在X64中一般只有快速调用方式即全部用寄存器来存储参数。可根据具体的环境来确定相关的调用约定和参数分配等。
在函数调用时,函数的参数的压栈顺序(右至左还是左至右,或者说从高地址到低地址还是相反)以及是否使用寄存器都有所不同。另外如果使用了栈,谁来负责栈的内存的管理;最后,大家都知道C++为了安全有一个改名机制,那么为了防止出现名称不对的现象,也得约定是否对名称进行修饰。

五、函数的调用过程和返回值控制

在分析了上述的函数相关技术后,就可以进行函数的调用过程分析了。函数的调用是通过一个栈来处理的,也就是说在栈的内存空间内(一个栈帧),存储着参数、返回地址、寄存器、局部变更和其它数据。看下面的图:
在这里插入图片描述

学习过栈的处理方式的就明白了,其实在函数调用过程中,就是找到函数的栈帧地址,然后按照约定将相关数据弹出,然后结束后再依照返回地址将数据返回。如果是需要使用寄存器进行处理时,寄存器的处理约定:
在这里插入图片描述

这些资料都可以在书籍和网上找到。说明的也非常清楚,如果想看一些细节,可以自己用汇编软件反编译处理一下,就明白了。
然后一般函数结束都会有返回值,对于返回值的处理,一般可有以下几种情况:
1、4字节及以内,使用eax寄存器处理,即返回写入此寄存器,调用者读取读此寄存器
2、4~8字节,通过rax寄存器传递
3、更大返回值,如一个对象。此处就涉及到各种不同的编译器版本和标准的不同的优化。举一个非优化的正常的流程,一般是调用者先开辟一段内存做为临时对象,然后将其传递给被调用者,被调用的函数将数据拷贝到此临时对象,同时将其指针保存在eax寄存器中。最后再将此临时对象拷贝给获取返回值的对象即可。
返回值的处理,情况非常多,大家要针对不同的情况来确定不同的场景,不能一概而论。特别是存在优化的情况下(可参看前面的RVO和NRVO相关的文章),一定要根据实际情况来分析,不能教条主义和本本主义。

六、总结

学习编程到最后会发现,以前学到的操作系统、计算机原理和编译原理等等基础的知识,都会有机的融合到一起。这才感叹,只是为了学习的方便和条理清晰,才拆分成了不同的技术体系。其实,它们是有起承转合的互相依赖互相包容的一个整体。
学习时要逐渐从点到线,再从线拉开一条面。最后在面的基础上,能形成多大的立体体系,就看个人的缘法和能力了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2189947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python——异常处理机制

Python 异常处理机制 Python异常与异常处理机制针对 Traceback 的解读try-except-else-finallyexcept语句except语句的机制在 except 语句中引用当前被处理的 Python 异常 finally语句finally语句执行后才能抛出未被处理的异常finally中执行return会导致异常丢失 raise 语句rai…

集合框架02:Collection使用(1)

视频链接:13.05 Collection使用(1)_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1zD4y1Q7Fw?p5&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 代码示例: package com.yundait.Demo01;import java.util.ArrayList; i…

hbuilderx+uniapp+Android健身房管理系统 微信小程序z488g

目录 项目介绍支持以下技术栈:具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是:数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 用户功能…

震撼!工业史上第一家万级别规模的工业数字化设备效果图平台

耗时八年打造,国内第一家万级别规模的工业数字化设备效果图平台 平台:www.kingview3d.cn 创作者:kingview3d郭工 行业:煤矿综合自动化、污水处理、净水处理、楼宇暖通、环保工程、医药废水处理、二供、无负压加压站、提升泵站、一…

模拟器GSN3之DHCP动态分配IP地址配置案例

前文《详解DHCP服务工作原理及配置案例》介绍了DHCP服务工作原理,要想彻底理解、应用DHCP服务,须通过实证案例学习,该文在GSN3虚拟环境下,构建DHCP服务的环境。 一、配置环境: 1、GSN3 2、路由器:R1、R2…

【微服务】服务注册与发现、分布式配置管理 - Consul(day5)

概述 作用 Consul的两大作用就是服务发现和注册与分布式配置管理。 服务发现在介绍Eureka组件的时候已经进行过详细概述,大概就是将硬编码到服务中的IP地址和端口号进行解耦,从而实现动态扩缩容、容错处理、服务管理等功能,通过服务注册和…

MAC备忘录空白解决方案

打开icloud->备忘录 取消勾选同步此MAC后再次勾选,然后点击完成即可。

<<迷雾>> 第7章 会变魔术的触发器(3)--R-S 触发器 示例电路

用来验证或非门反馈功能的完整电路 info::操作说明 如演示出现异常, 可点右侧面板的重置按钮重置 此处 R 和 S 都使用的是按钮开关 点击 R 可让 Q 熄灭 点击 S 可让 Q 亮起 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/cyjsjd…

针对线上消息积压的排查思路以及解决方案

一、背景 我们在日常工作中,经常会碰到线上告警,消息队列消息积压了,试想如果对消息的消费速率有要求的场景,消息积压一定会或多或少对自己本身的业务场景有影响,这里就针对消息积压的场景,谈谈具体的排查…

过滤器Filter【详解】

过滤器Filter 1、 现有问题 在以往的Servlet中,有冗余的代码,多个Servlet都有重复的代码 比如编码格式设置 登录信息认证 2、 概念 过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术。 过滤器 3、 过滤器作用 执…

Python办公自动化教程(006):Word添加标题

2.3 word标题 介绍: 在 python-docx 中,您可以使用 add_heading() 方法为文档添加标题。此方法允许您指定标题的文本和级别(例如,一级标题、二级标题等)。标题级别的范围是从 0 到 9,其中 0 表示文档的主标…

深度解析:从浏览器输入链接到页面展现的奇幻历程

〇、前言 当我们在浏览器中输入一个网址,例如:example.com,按下回车键后,会发生什么呢? 主要会发生以下这些过程:域名解析、建立HTTP连接、发送HTTP请求、数据传输、渲染网页、断开HTTP连接。 一、域名解…

类型转换【C++提升】(隐式转换、显式转换、自定义转换、转换构造函数、转换运算符重载......你想知道的全都有)

更多精彩内容..... 🎉❤️播主の主页✨😘 Stark、-CSDN博客 本文所在专栏: C系列语法知识_Stark、的博客-CSDN博客 座右铭:梦想是一盏明灯,照亮我们前行的路,无论风雨多大,我们都要坚持不懈。 一…

【srm系统】供应商管理,招投标管理,电子采购系统,询价管理

前言: 随着互联网和数字技术的不断发展,企业采购管理逐渐走向数字化和智能化。数字化采购平台作为企业采购管理的新模式,能够提高采购效率、降低采购成本、优化供应商合作效率,已成为企业实现效益提升的关键手段。系统获取在文末…

[含文档+PPT+源码等]精品基于Python实现的美术馆网站的设计与实现

基于Python实现的美术馆网站,其设计与实现背景主要源于以下几个方面的需求和发展趋势: 一、文化艺术领域的发展需求 随着文化娱乐活动的日益丰富,美术馆作为展示艺术作品、传播文化的重要场所,其管理和服务模式的创新对于提升公…

LabVIEW提高开发效率技巧----使用动态事件

在LabVIEW开发过程中,用户交互行为可能是多样且不可预知的。为应对这些变化,使用动态事件是一种有效的策略。本文将从多个角度详细介绍动态事件的概念及其在LabVIEW开发中的应用技巧,并结合实际案例,说明如何通过动态事件提高程序…

【售后资料】软件售后服务方案(word原件)

软件售后服务方案的售后服务范围广泛,涵盖了多个方面,以确保客户在使用软件过程中得到全面、及时的支持。具体来说,这些服务范围通常包括以下几个核心内容: 技术支持服务维护与更新服务培训与教育服务定制化服务数据管理与服务客户…

如何获取网页内嵌入的视频?

如何获取网页内嵌入的视频? 有时插件无法识别的视频资源,可以通过手动使用浏览器的开发者工具来抓取。你可以按照以下步骤操作: 步骤: 打开网页并按 F12:在视频页面按下 F12 或右键点击网页并选择“检查”或“Inspe…

Spring Boot实现的大学生就业市场解决方案

1系统概述 1.1 研究背景 如今互联网高速发展,网络遍布全球,通过互联网发布的消息能快而方便的传播到世界每个角落,并且互联网上能传播的信息也很广,比如文字、图片、声音、视频等。从而,这种种好处使得互联网成了信息传…

【案例】距离限制模型透明

开发平台:Unity 2023 开发工具:Unity ShaderGraph   一、效果展示 二、路线图 三、案例分析 核心思路:计算算式:透明值 实际距离 / 最大距离 (实际距离 ≤ 最大距离)   3.1 说明 | 改变 Alpha 值 在 …