main函数之前做了什么?

2023-05-16

main函数之前--真正的函数执行入口或开始

一种解释

实际上,在可执行文件被加载之后,控制权立即交给由编译器插入的Start函数,它将对后面这些全局变量进行准备:
   _osver 操作系统的构件编号
  _winmajor 操作系统的主版本号
  _winminor 操作系统的次版本号
  _winver 操作系统完全版本号
  __argc 命令行参数个数
  __argv 指向参数字符串的指针数组
  _environ 指向环境变量字符串的指针数组
Start函数初始化堆并调用main函数.mian函数返回之后,Start函数调用Exit函数结束该进程.
启动函数Start的源代码在:
   crt0.c Microsoft Visual C++
  c0w.asm Borladn C++

另一种解释

Some of the stuff that has to happen before main():  
set up initial stack pointer  
initialize static and global data  
zero out uninitialized data  
run global constructors

Some of this comes with the runtime library's crt0.o file or its __start() function. Some of it you need to do yourself.
Crt0 is a synonym for the C runtime library.  
Depending on the system you're using the follwing may be incomplete, but it should give you an idea. Using newlib-1.9.0/libgloss/m68k/crt0.S as an outline, the steps are:  
1. Set stack pointer to value of __STACK if set  
2. Set the initial value of the frame pointer  
3. Clear .bss (where all the values that start at zero go)  
4. Call indirect of hardware_init_hook if set to initialize hardware  
5. Call indirect of software_init_hook if set to initialize software  
6. Add __do_global_dtors and __FINI_SECTION__ to the atexit function so destructors and other cleanup functions are called when the program exits by either returning from main, or calling exit  
7. setup the paramters for argc, argv, argp and call main  
8. call exit if main returns

第三种解释:囫囵C语言(三):谁调用了我的 main?
    
    现在最重要的是要跟得上潮流,所以套用比较时髦的话,谁动了我的奶酪。谁调用了我的 main?不过作为计算机工作者,我劝大家还是不要赶时髦,今天Java热,明天 .net 流行,什么时髦就学什么。我的意思是先花几年把基本功学好,等你赶时髦的时候也好事半功倍。废话不多说了。
    
    我们都听说过一句话:“main是C语言的入口”。我至今不明白为什么这么说。就好像如果有人说:“挣钱是泡妞”,肯定无数砖头拍过来。这句话应该是“挣钱是泡妞的一个条件,只不过这个条件特别重要”。那么上面那句话应该是 “main是C语言中一个符号,只不过这个符号比较特别。”
    
    我们看下面的例子:
    
    /* file name test00.c */
    
    int main(int argc, char* argv)
    {
     return 0;
    }
    
    编译链接它:
    cc test00.c -o test.exe
    会生成 test.exe
    
    但是我们加上这个选项: -nostdlib (不链接标准库)
    cc test00.c -nostdlib -o test.exe
    链接器会报错:
    undefined symbol: __start
    
    也就是说:
    1. 编译器缺省是找 __start 符号,而不是 main
    2. __start 这个符号是程序的起始点
    3. main 是被标准库调用的一个符号
    
    再来思考一个问题:
    我们写程序,比如一个模块,通常要有 initialize 和 de-initialize,但是我们写 C 程序的时候为什么有些模块没有这两个过程么呢?比如我们程序从 main 开始就可以 malloc,free,但是我们在 main 里面却没有初始化堆。再比如在 main 里面可以直接 printf,可是我们并没有打开标准输出文件啊。(不知道什么是 stdin,stdout,stderr 以及 printf 和 stdout 关系的群众请先看看 C 语言中文件的概念)。
    
    有人说,这些东西不需要初始化。如果您真得这么想,请您不要再往下看了,我个人认为计算机软件不适合您。
    
    聪明的人民群众会想,一定是在 main 之前干了些什么。使这些函数可以直接调用而不用初始化。通常,我们会在编译器的环境中找到一个名字类似于 crt0.o 的文件,这个文件中包含了我们刚才所说的 __start 符号。(crt 大概是 C Runtime 的缩写,请大家帮助确认一下。)
    
    那么真正的 crt0.s 是什么样子呢?下面我们给出部分伪代码:
    
    ///
    section .text:
    __start:
    
     :
     init stack;
     init heap;
     open stdin;
     open stdout;
     open stderr;
     :
     push argv;
     push argc;
     call _main; (调用 main)
     :
     destory heap;
     close stdin;
     close stdout;
     close stderr;
     :
     call __exit;
    
    
    实际上可能还有很多初始化工作,因为都是和操作系统相关的,笔者就不一一列出了。
    
    注意:
    1. 不同的编译器,不一定缺省得符号都是 __start。
    2. 汇编里面的 _main 就是 C 语言里面的 main,是因为汇编器和C编译器对符号的命名有差异(通常是差一个下划线'_')。
    3. 目前操作系统结构有两个主要的分支:微内核和宏内核。微内核的优点是,结构清晰,简单,内核组件较少,便于维护;缺点是,进程间通信较多,程序频繁进出内核,效率较低。宏内核正好相反。我说这个是什么目的是:没办法保证每个组件都在用户空间(标准库函数)中初始化,有些组件确实可能不要初始化,操作系统在创建进程的时候在内核空间做的。这依赖于操作系统的具体实现,比如堆,宏内核结构可能在内核初始化,微内核结构在用户空间;即使同样是微内核,这个东东也可能会被拿到内核空间初始化。
    
    随着 CPU 技术的发展,存储量的迅速扩展,代码复杂程度的增加,微内核被越来越多的采用。你会为了 10% 的效率使代码复杂度增加么?要知道每隔 18 个月 CPU 的速度就会翻一番。所以我对程序员的要求是,我首先不要你的代码效率高,我首先要你的代码能让 80% 的人迅速看懂并可以维护。

总结:

main函数执行之前,主要就是初始化系统相关资源:

1.设置栈指针

2.初始化static静态和global全局变量,即data段的内容

3.将未初始化部分的赋初值:数值型short,int,long等为0,bool为FALSE,指针为NULL,等等,即.bss段的内容

4.运行全局构造器,估计是C++中构造函数之类的吧

5.将main函数的参数,argc,argv等传递给main函数,然后才真正运行main函数

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

main函数之前做了什么? 的相关文章

  • catkin_make遇到 gazebo_ros_controlConfig.cmake相关的问题

    现象 xff1a Could not find a package configuration file provided by gazebo ros control with any of the following names 解决方法
  • 一些vscode自动提示报错

    Pointer to incomplete class type is not allowed 通常是由于类声明了但是没有定义造成的 xff0c 需要做的是在错误文件里面引用下这个类 xff1a class Test xff1b a poi
  • bazel一些用法

    1 编译东西 要在根目录下 xff0c 和WORKSPACE在同一级 例如 xff0c 对于bazelbuild examples 而BUILD文件一般与源文件并列 examples cpp tutorial stage1 main BUI
  • 第十一节std::atomic原子操作

    一 原子操作 1 1原子操作概念例子 互斥量 xff1a 多线程编程中保护共享数据 xff1a 锁 xff0c 操作共享数据 xff0c 开锁 有两个线程 xff0c 对一个变量进行操作 xff0c 这个线程读 xff0c 另一个线程往变量
  • 用Ceres实现PnP

    在ceres中实现PnP优化 xff08 仅优化位姿 xff09 视觉SLAM十四讲 课后习题 ch7 xff08 更新中 xff09
  • deque insert()函数几种用法

    C 43 43 deque insert 用法及代码示例
  • Matplotlib error: No such file or directory: ‘latex‘: ‘latex‘

    Matplotlib error No such file or directory latex latex span class token function sudo span apt span class token function
  • 在ROS下Intel RealSense D435i 驱动的安装,避免踩坑,避免缺少imu话题等各种问题(适用于D400系列、SR300和T265跟踪模块等)

    版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net AnChenliang 1002 article details 109454465 目录 背景 方法1 使用apt安装 不建议使用此方法 了解一下
  • wsl作为开发主机与开发板联调

    linux开发经历记录 wsl作为开发主机与开发板联调 uboot使用nfs网络挂载时使用hanewin搭建win10的nfs servers 背景介绍 小白学习linux开学 xff0c 不想用VM虚拟机作为开发平台 xff0c 恰好了解
  • weka中文乱码解决办法

    由于weka的默认字符集编码是Cp1252 xff0c 所以如果你导入的数据中有中文字符 xff0c 就会出现乱码的情况 xff0c 所以需要weka的RunWeka ini文件 将cp1252替换成你的数据对应的字符集编码 xff0c 比
  • 动态库和静态库的区别

    静态库 xff1a 这类库的名字一般是libxxx a xff1b 1 利用静态函数库编译成的文件比较大 xff0c 因为整个函数库的所有数据都会被整合进目标代码中 xff0c 他的优点就显而易见了 xff0c 2 即编译后的执行程序不需要
  • 重复数据删除技术(Data Deduplication)

    我相信所有人都会同意 xff0c 数据存储正在以飞快地 xff0c 甚至是令人震惊的速度在增长 这意味着为了不影响普通用户的正常使用 xff0c 存储管理员们不得不加班加点地在幕后 工作着 他们的鲜为人知的工作包括 xff1a 配额管理 x
  • TCP/IP协议

    TCP IP 协议栈是一系列网络协议的总和 xff0c 是构成网络通信的核心骨架 xff0c 它定义了电子设备如何连入因特网 xff0c 以及数据如何在它们之间进行传输 TCP IP 协议采用4层结构 xff0c 即应用层 传输层 网络层和
  • 趣谈网络协议-云计算中的协议

  • ros里Catkin的CMakelists/package.xml

    Catkin是基于CMake的编译构建系统 xff0c 具有以下特点 xff1a Catkin沿用了包管理的传统像 find package 基础结构 pkg config扩展了CMake xff0c 例如 软件包编译后无需安装就可使用 自
  • js根据坐标进行图片截图,获取图片上指定位置的截图

    根据坐标截取图片上指定的区域 xff0c 坐标可以是规则的图片截取 xff0c 也可以是不规则的图片截取 实现思路 xff1a 规则裁剪自然不用多说 xff0c 我们使用画布的getImageData x y width height 方法
  • 浅谈APM系列-----update_flight_mode(ModeAltHold)

    update flight mode xff08 ModeAltHold xff09 这里只看ModeAltHold 位置 xff1a X ardupilot ArduCopter mode cpp update flight mode c
  • 多态的总结

    对于多态 xff0c 可以总结以下几点 xff1a 一 使用父类类型的引用指向子类的对象 xff1b 二 该引用只能调用父类中定义的方法和变量 xff1b 三 如果子类中重写了父类中的一个方法 xff0c 那么在调用这个方法的时候 xff0
  • android 深度图

    在 Android开发中自定义控件是一个范围很广的话题 xff0c 讲起自定义控件 xff0c 从广度上来划分的话 xff0c 大体上可以划分为 xff1a View ViewGroup的绘制事件分发各种动画效果滚动嵌套机制还有涉及到相关的
  • 在配置Intel realsense (D435i)时遇到的问题

    1 第一次配置相机时 配置完成后 运行相机报以下错误 02 11 20 50 18 674 WARNING 140196725126912 messenger libusb cpp 42 control transfer returned

随机推荐

  • Robosense M1/速腾半固态激光雷达M1 保姆级教程1-如何连接雷达?

    引言 当我们拿到M1雷达时 xff0c 可能会因为激光雷达是一个新的设备 xff0c 没有用过 xff0c 而感到紧张和局促 没有关系 xff0c 通过阅读文本 xff0c 可以让你轻而易举的上手使用激光雷达 1认识M1接口 图中较粗的接口
  • PMP(一):知识要点汇总

    开篇 首先恭喜自己成为 项目管理专业人士 的一员 xff0c 本专题旨在帮助自己重新梳理整个的知识体系以及后续对于项目管理的理解与尝试 系列一 xff1a 知识要点汇总 以下内容是我在备考和考完后对于部分知识要点的一个汇总和总结 xff0c
  • git在vscode中的使用

    git在vscode中的使用 vscode 作为前端使用较多的软件 xff0c 平时的git操作不可避免 xff0c 但是利用vscode自带的功能和插件 xff0c 可以让我们的工作效率提高不少 项目准备 直接clone span cla
  • 获利空间看刘嘉玲理论来看;乐扣乐扣尽量靠近k

    i tiboo cn 1768805 i tiboo cn 1768806 i tiboo cn 1768807 i tiboo cn 1768810 i tiboo cn 1768813
  • 我见过最清晰的--理解梯度,散度,旋度

    作者 xff1a FRANK WANG 链接 xff1a https www zhihu com question 24074028 answer 26657334 来源 xff1a 知乎 梯度 运算的对像是纯量 运算出来的结果会是向量在一
  • 视觉应用工程师-环境安装教学视频-Mac系统其他操作

    立即学习 https edu csdn net course play 29993 432706 utm source 61 blogtoedu Mac系统安装miniconda搭建深度学习环境 安装 Conda是一个开源的包 环境管理器
  • Windows 环境下安装Redis 5.0.x 服务图文教程

    Windows 环境下安装Redis 5 0 x 服务图文教程 Redis官网并没有提供windows的安装包 xff0c github有第三方制作的windows安装包 下载地址 xff1a https github com tporad
  • Python 爬虫+可视化,手把手教你使用 Python 爬取 JD 网站并且可视化展示

    当你看到别人使用 Python 网络爬虫做出一些高大上的项目你是否也有那么一点点的心动 xff1f 羡慕别人用几行简单的代码就能获取到自己想要的数据 xff1f 羡慕别人用几行代码就能做出优美的可视化图案 xff1f 我将使用最新 Pyth
  • 推荐系统实践:基于数据集MovieLens构造简单推荐系统

    摘要 本文基于 MovieLens 数据集构造了用户 电影项目评价矩阵 xff0c 并基于评价矩阵计算两用户间的相似度 xff0c 取出相似度最高的 N 个用户作为候选用户序列 接着筛选出这 N 个候选用户的高分电影项目且当前用户尚未观看
  • Flask 入门教程:Jinja2模板用法

    Jinja2模板引擎简介 模板 在前面的示例中 xff0c 视图函数的主要作用是生成请求的响应 xff0c 这是最简单的请求 实际上 xff0c 视图函数有两个作用 xff1a 处理业务逻辑和返回响应内容 在大型应用中 xff0c 把业务逻
  • VINS-mono中坐标系定义以及通过VINS-mono求解无人机位姿

    因为在科研中需要使用VINS mono算法来为无人机提供位姿估计信息 因此需要搞清楚VINS mono相应坐标系以及无人机坐标系之间的关系 目录 1 坐标系关系 1 1 VINS mono坐标系定义 1 2 无人机坐标系 2 通过VINS
  • Github Copilot 开始收费了, 帮你列出些替代的插件

    今天打开 VSCode xff0c 弹出了Github Copilot 开始收费的通知 可以免费用到 8 月 22 日 xff0c 每月 70 元还是有些小贵 这里给大家推荐一些替代品 xff1a Kite https www kite c
  • 如何在 Ubuntu上使用 Nginx 设置密码验证

    介绍 设置 Web 服务器时 xff0c 您通常希望限制访问网站的某些部分 Web 应用程序通常提供自己的身份验证和授权方法 xff0c 但如果这些方法不充分或不可用 xff0c 则可以使用 Web 服务器本身来限制访问 在本指南中 xff
  • 使用Argo CD和GitOps持续部署到Kubernetes

    引言 使用Kubernetes部署你的应用程序可以提供显著的基础设施优势 xff0c 例如灵活的伸缩 分布式组件的管理以及对应用程序不同版本的控制 然而 xff0c 随着控制的增加 xff0c 复杂性也随之增加 持续集成和持续部署 CI C
  • GitHub Codespaces 的配置

    CPU xff1a 4x Xeon 64 2 60 GHz 轻度开发够用 xff0c 要是编译什么稍微复杂一点的项目 估计会CPU跑满 内存 xff1a 8G xff0c 勉强够用 自用的Mac 16G都感觉不太够 硬盘 xff1a 32G
  • 使用Zoundry在CSDN发布Blog

    安装一个Zoundry吧 xff0c 用这个来离线写Blog xff0c 再也不怕突然断线和丢失文章了 Zoundry是用Python实现的一个离线撰写Blog工具 支持Community Servedr blogger com Wordp
  • Python中Array的常用操作(二)数组基本操作

    1 数组操作 x代表数组中的元素 xff0c i代表位置 a append x 把元素x添加到数组的尾部 b insert i x 把元素x 插入到位置i c remove x 删除第一个元素x d pop i 删除第i个元素 xff0c
  • Python中Array的常用操作(三)数组高级操作

    1 抽取数组中不重复的数据 gt gt gt a 61 x 2 for x in range 1 5 2 gt gt gt uniq 61 list set a 8 2 4 6 gt gt gt uniq 61 sorted set a 2
  • 2011年,移动互联网加速蔓延 – 来自2011移动开发者大会

    2011移动开发者大会 xff0c 这是第二届移动开发者大会了 xff0c 这一年来移动互联网各个领域蔓延开来 xff0c 蔓延这个词是开复老师演讲的主题 从事塞班开发的请举手 xff0c 举手者寥寥 记得在去年移动开发者大会上 xff0c
  • main函数之前做了什么?

    main函数之前 真正的函数执行入口或开始 一种解释 实际上 xff0c 在可执行文件被加载之后 xff0c 控制权立即交给由编译器插入的Start函数 xff0c 它将对后面这些全局变量进行准备 xff1a osver 操作系统的构件编号