深入理解《hello world》是如何实现的

函数栈桢的创建和销毁

  • 前言
  • C语言是由函数构成的
  • 栈帧概念
  • 寄存器
  • hello world是如何实现
    • 我们转到汇编代码
    • 🌳 main函数栈帧的创建(开始调用main函数)
    • 🌳 main函数栈帧的初始化
    • 🌳函数栈帧的销毁
      • printf函数栈帧的销毁
      • main函数的栈帧销毁
    • 总结

❤️ :热爱编程学习,期待一起交流。 🙏:博主是河牧院大一在读学生,水平有限,如发现错误,期待指点!(2466200050)
🌳:以下是我对main函数栈帧的创建与销毁一些拙见,期待大佬们指教。

前言

在这里插入图片描述

  • 了解函数栈桢的目的是提高我们的基础知识功底,了解反汇编和内存,而不是会printf一个hello world,但不知道他是如何实现的,知其所以然。虽然学了这些并不能提高我们的算法能力,但看看到底是怎么运行的,有助于后期的学习,使我们向看代码是内存这个境界更近一步。
  • 正如图上达克效应一样,横坐标代表技术。纵坐标代表自信。我们并没有想象中的那么优秀,要学会从他人眼里看到自己的影子。也许你现在处于愚昧之巅,也许你处在绝望之谷,不过这都是正常的,只要我们认清自己,持续输出,一定会走向开悟之坡。

C语言是由函数构成的

  • C语言是由函数为单元模块构成的,不信的话,可以想象一下,每一次我们用C语言编写程序的时候,都需要写一个main()。而main()就是一个函数。
  • 就拿最简单的打印一句hello world来说,不就是在main函数里面的的吗。
  • 所以我们了解函数栈帧的创建和销毁,其实就在研究一个代码是如何实现的。
  • 我们在这里要用到汇编代码来演示函数栈帧的创建与销毁。

栈帧概念

  • C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。

  • 栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构。

  • 首先应该明白,栈帧是存放在内存中的栈区的。栈帧是栈区分配给进程的内存区
    在这里插入图片描述

  • 栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)。

寄存器

ebp:栈底指针
esp:栈顶指针
esp和ebp是用来维护函数的。

  • 寄存器有很多,但这里我们主要用到一下两种寄存器,ebp和esp。
  • 这两个寄存器存放的是地址。用来维护函数栈帧。所以我们可以把它俩个可以叫做指针。指针不就是用来存放地址的嘛。
  • 我们平时用C语言写的每一个程序都包含了函数,而每一个函数的调用,都要在栈区创建一个空间。这个空间区域就叫做函数栈帧。而ebp和esp就是用来维护这片区域的。

hello world是如何实现

  • 这里我们需要明白
  • main函数是一个程序的入口,main函数有且只能有一个。
  • 我们在进入这个程序的时候,首先需要调用main函数,你没听错,就是调用它
  • 那么是谁调用的main函数呢?它是被一个简称叫做CRT的函数所调用的。(CRT是我自己命名的简称,我只要知道main函数是被它调用的就好了。)
#include<stdio.h>
int main()
{printf("hello world");return 0;
}
  • 看到这段在main函数里面的代码。有人就乐了,不就是一个printf就可以打印出来了吗?
  • 是的,没错,的确是一个printf就打印出来了。
  • 但是在执行printf这句语句的时候,编译器要做大量的工作。这里的工作就是指函数栈帧的创建

我们转到汇编代码

  • 这里我用的是vs2019编译器下转到反汇编查看的。
  • 红色的框就是ebp指针和esp指针从维护CRT函数转变到维护main函数的过程。
  • 绿色的框就是我们程序代码。
    在这里插入图片描述

🌳 main函数栈帧的创建(开始调用main函数)

  • 下面是esp和ebp维护CRT函数栈帧的图片
    在这里插入图片描述

  • 首先进行第一条指令
    在这里等等述

  • push的意思就是压栈,就是将ebp放到栈顶。

  • 注意:这是为了将来main函数返回之后,esp寄存器和ebp寄存器还能来回来维护CRT函数的,这里push的ebp就是为以后调用完返回CRT函数埋下的伏笔。

在这里插入图片描述* 压栈的同时esp指针也会随着向上走。CRT函数的栈帧也随之增加

在这里插入图片描述* 接着执行第二条指令
在这里插入图片描述

  • mov是move的缩写,意思是将esp赋值给ebp,实质是将esp里面的地址放到ebp里面。(也就是两个指针指向了同一位置)
    在这里插入图片描述
    注意:
  • 此时ebp和esp没有在维护CRT函数了,但他的函数栈帧没有销毁,因为栈空间的使用只能先销毁低地址,再销毁高地址。即图中的从上往下销毁。
  • 第三条指令

在这里插入图片描述

  • sub是减法的英文。意思是将esp这个地址减去C0这个16进制数字。C0其实就是十进制的192.可以在电脑上打开计算器,切换为程序员模式进行计算。(esp-192)
  • h是一个标识符,不用管它

在这里插入图片描述* esp-192就是esp指针从低地址移向了高地址。而此时就呈现出来了一个main函数栈帧的雏形。ebp和esp之间的就是他的雏形。

在这里插入图片描述* 接下来执行第四,五,六条指令。(可以不用管这三条指令)

在这里插入图片描述

  • 这里是连续三次(push)压栈,为了保存这三个寄存器。压栈的同时,esp指针位置随之上升。main函数的栈帧也随之扩大。

在这里插入图片描述

  • 到这里main函数的函数栈帧初步创建成功。

🌳 main函数栈帧的初始化

在这里插入图片描述

  • 这四步骤就是将ebp到esp之间的空间初始化为cc cc cc cc。
  • 这些cc cc cc cc是随机值。

在这里插入图片描述* 然后执行这两条命令
在这里插入图片描述
在这里插入图片描述

  • 这里的call是调用的意思。就是调用printf函数来打印hello world。这里我就不赖细究printf函数怎么调用了。触及到博主目前知识水平极限了。
  • 保存002e1339这个地址的作用是为了调用完printf函数后返回主调函数,执行下一条指令。
    在这里插入图片描述

🌳函数栈帧的销毁

printf函数栈帧的销毁

  • 调用完printf函数后,printf函数它的栈帧就要销毁了。
    在这里插入图片描述
  • add的意思是让esp加4,即栈顶指针向下移动,来实现栈帧销毁。

在这里插入图片描述

  • 这个xor指令的意思为异或,两个相同的数异或就为0(实质是设置返回值为0)

main函数的栈帧销毁

  • main函数栈帧的销毁遵循后进先出的原则

  • 首先连续执行三个pop(弹出),把三个寄存器还原回去。
    在这里插入图片描述在这里插入图片描述

  • 我们让esp加上0C0h,那么esp将会往下移动到ebp的位置。

  • 官方语言是:降低栈顶esp的位置,此时局部变量空间被释放。

  • 此时main函数的栈帧就销毁了。
    在这里插入图片描述在这里插入图片描述

  • 接着的话esp和ebp指针会重新去维护调用main函数的函数栈帧

总结

  • 每一次的函数调用都要在栈区开辟相应的栈帧空间。并将空间的内容进行初始化。
  • 为什么平时写程序时没有赋值的值都是随机值?因为局部变量就是在函数栈帧里创建的。局部变量的值是我们初始化的cc cc cc cc。cc cc cc cc就是随机值
  • 函数调用是怎么返回的?我们首先push了一个ebp寄存器,这样调用完之后就可以根据ebp这个地址返回了。
  • 如果你觉得我的文章对你有帮助🎉欢迎关注🔎点赞👍收藏⭐️留言📝。

参考文献:《C++反汇编与逆向分析技术揭秘》

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

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

相关文章

【供应链架构day8】履约系统的架构长什么样子:从需求开始讲起

很多公司&#xff0c;除了自营商城以外&#xff0c;还有其它渠道&#xff08;如天猫、京东等&#xff09;&#xff0c;多个渠道的订单该如何集中履约&#xff1f;订单履约全流程是怎样的&#xff1f;接着小Q的故事&#xff0c;为您揭晓多平台订单履约系统的系统设计思路。 由于…

金融反欺诈-交易基础介绍

一、简介 如今&#xff0c;互联网金融比较火热&#xff0c;金融欺诈也变得非常普遍&#xff0c;金融反欺诈也应运而生。本文将主要介绍下金融交易中的一些基本内容&#xff0c;并简单介绍下历史悠久的并且还未淘汰的磁条卡的风险&#xff0c;这些也是了解金融欺诈需要的基本知识…

详解反调试技术

反调试技术&#xff0c;恶意代码用它识别是否被调试&#xff0c;或者让调试器失效。恶意代码编写者意识到分析人员经常使用调试器来观察恶意代码的操作&#xff0c;因此他们使用反调试技术尽可能地延长恶意代码的分析时间。为了阻止调试器的分析&#xff0c;当恶意代码意识到自…

stl文件的解析和在线3d打印

什么是stl文件 STL(Stereolithography)文件&#xff0c;由3D Systems于1987年创建&#xff0c;并且已被广泛用作全行业3D打印机模型的标准文件。它有一些别的首字母缩写词如“标准三角语言(Standard Triangle Language)”&#xff0c;“标准曲面细分语言(Standard Tessellatio…

\r \r\n \t的区别,是什么意思

分享一下我老师大神的人工智能教程吧。零基础&#xff0c;通俗易懂&#xff01;风趣幽默&#xff01;http://www.captainbed.net/ 也欢迎大家转载本篇文章。分享知识&#xff0c;造福人民&#xff0c;实现我们中华民族伟大复兴&#xff01; \n 软回车&#xff1a; 在Windo…

著名的 P=NP 问题到底是什么?

△点击上方“Python猫”关注 &#xff0c;回复“1”领取电子书 大家好&#xff0c;我是猫哥。我最近在追一部热播的电视剧《天才基本法》&#xff0c;它反复提到了“PNP”问题。这可是一个天大的难题&#xff0c;在 2000 年克雷数学研究所公布的千禧年七大数学难题中&#xff0…

PCIe 是什么 ? -- 基本知识

1. 概述 1&#xff09;PCIe(Peripheral Component Interconnect Express)是继ISA和PCI总线之后的第三代I/O总线。一般翻译为周边设备高速连接标准。 2&#xff09;PCIe协议是一种端对端的互连协议&#xff0c;提供了高速传输带宽的解决方案。目前PCIe已经发展到第四代PCIe4.0, …

反欺诈概念库-信用卡反欺诈管理

原文&#xff1a;http://www.cnki.com.cn/Article/CJFDTotal-XYKZ200508004.htm 2005年6月&#xff0c;美国爆出4000万张信用卡资料外泄的特大新闻。消息传来&#xff0c;舆论哗然。尽管我国只有数千个信用卡账户数据资料受波及&#xff0c;但一石激起千层浪&#xff0c;国内金…

打印DPI如何与计算机DPI一致,打印效果失真 你了解DPI与照片关系么?

今天我们来聊一下关于分辨率的问题,分辨率这个词看似遥远,但是却和你的照片息息相关,文章开始之前我先向大家抛出一个问题,“我们要打印A4尺寸的照片,照片的像素至少要多大?”如果您能轻松的回答上来这个问题,那么这篇文章对于您的意义就不大了。 其实关于打印照片尺寸的…

常说的监听某个端口,是什么意思?怎么理解?

▲ 点击上方“分布式实验室”关注公众号 回复“1”抽取纸质技术书 今天这篇文章&#xff0c;想用一个故事和你讲讲端口监听是怎么回事。耐心往下看。 在学生会大楼的角落里&#xff0c;有一家咖啡店&#xff0c;在咖啡店的角落里有两个学生。利兹敲打着她哥哥在她搬到大学时给她…

RWKV – transformer 与 RNN 的强强联合

在 NLP (Natural Language Processing, 自然语言处理) 领域&#xff0c;ChatGPT 和其他的聊天机器人应用引起了极大的关注。每个社区为构建自己的应用&#xff0c;也都在持续地寻求强大、可靠的开源模型。自 Vaswani 等人于 2017 年首次提出 Attention Is All You Need 之后&am…

chatgpt赋能python:Python中的或运算:学习这个重要概念

Python中的或运算&#xff1a;学习这个重要概念 或运算是Python编程语言中一个重要的概念。了解如何使用或运算可以帮助程序员编写更有效和有意义的代码。在此文章中&#xff0c;我们将介绍Python中或运算的基础知识以及如何使用它来编写各种类型的代码。 什么是或运算&#…

智慧工厂主题 Meetup 线下报名+福利开启!IoTDB X EMQ 构建数据平台赋能智能制造...

随着全球制造业的竞争日益激烈&#xff0c;智慧工厂成为当今制造业的重要趋势之一。智慧工厂采用了先进的物联网、大数据等科技手段&#xff0c;以期通过智能化、数字化管理和生产&#xff0c;实现高度自动化和高效生产。因此&#xff0c;如何通过计算分析挖掘生产数据价值&…

《计算机组成原理》唐朔飞 第8章 CPU的结构和功能 - 学习笔记

写在前面的话&#xff1a;此系列文章为笔者学习计算机组成原理时的个人笔记&#xff0c;分享出来与大家学习交流。使用教材为唐朔飞第3版&#xff0c;笔记目录大体与教材相同。 网课 计算机组成原理&#xff08;哈工大刘宏伟&#xff09;135讲&#xff08;全&#xff09;高清_…

常用方法——7.JS 给数组排序 es6

let arrObj[{"name": "银行转账","value": 2}, {"name": "支付宝支付","value": 1}, {"name": "微信支付","value": 0} ] arrObj.sort((a,b)>{ return a.value-b.value})//升序…

JS数组对象排序(es6)

效果&#xff1a;升序&#xff1a; 降序&#xff1a; 升序是&#xff1a;a.value-b.value 降序是&#xff1a;b.value-a.value 代码&#xff1a; let arrObj[{"name": "银行转账","value": 2},{"name": "支付宝支付","…

微信小程序根据日期和时间进行排序

一、前言 最近接手了一个小程序的项目&#xff0c;有这样一个需求要对列表进行日期和时间的排序&#xff0c;于是小试牛刀&#xff0c;操作了一番&#xff0c;终于搞出来&#xff0c;在这里给大家总结分享一下经验&#xff0c;希望对大家有一定的帮助。 二、需求分析&#xf…

代码覆盖率

在做单元测试时&#xff0c;代码覆盖率常常被拿来作为衡量测试好坏的指标&#xff0c;甚至&#xff0c;用代码覆盖率来考核测试任务完成情况&#xff0c;比如&#xff0c;代码覆盖率必须达到80&#xff05;或 90&#xff05;。于是乎&#xff0c;测试人员费尽心思设计案例覆盖代…

【零散技术】微信小程数组排序

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 目录 一&#xff1a;业务功能 二&#xff1a;代码实现 在国内&#xff0c;微信小程序的生态已经完全渗透至各行各业&#xff0c;无一幸免。 今天分享一个常用组件的功能&#xff1a;排序 一&#xff1a;业务功能 以订单排序…

js--数组排序

微信扫码关注公众号 &#xff1a;前端前端大前端&#xff0c;追求更精致的阅读体验 &#xff0c;一起来学习啊关注后发送关键资料,免费获取一整套前端系统学习资料和老男孩python系列课程 学习资源推荐 js [1,5,3].sort(function (a,b) { return a-b; }) //[1,3,5] [1,5,3].s…