当前位置:我的异常网» C语言 » 一个c程序在执行main函数之前和main之后都做了那些

一个c程序在执行main函数之前和main之后都做了那些事情啊该如何解决

www.myexceptions.net  网友分享于:2013-04-17  浏览:19次

一个c程序在执行main函数之前和main之后都做了那些事情啊?

很想知道

一个c程序在执行main函数之前和main之后都做了那些事情?

请高手指点指点哈~

------解决方案--------------------

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编译器对符号的命名有差异(通常是差一个下划线'_')。

文章评论

c语言程序执行完main函数后,一个c程序在执行main函数之前和main之后都做了那些事情啊该如何解决...相关推荐

  1. PyCharm 中选中一个变量/函数后,所有用到这个变量/函数的地方高亮显示,改配色方案

    由于 PyCharm 原来的配色方案里面,选中一个变量/函数后,所有用到这个变量/函数的地方高亮显示得实在太不明显了. 所以要改成高亮! 找了好久才找到,所以在博客里记录一下,希望对大家有帮助,当然也 ...

  2. ip地址转换数字函数 iton_c# – RabbitMQ CreateConneciton问题 – 在一个应用程序中运行,但在另一个应用程序中运行...

    所以这是连接代码. var factory = new ConnectionFactory { HostName = "myserver", UserName = "te ...

  3. 微信小程序实现跳转到另外一个小程序的方法

    微信小程序实现跳转到另外一个小程序的方法 1,首先需要在当前小程序app.json中定义:需要跳转的小程序的app-id app.josn "navigateToMiniProgramApp ...

  4. 应用FileInputStream类,编写应用程序,从磁盘上读取一个Java程序,并将源程序代码显示在屏幕上

    应用FileInputStream类,编写应用程序,从磁盘上读取一个Java程序,并将源程序代码显示在屏幕上. package p1;import java.io.*; public class FI ...

  5. android启用其他应用程序,杀死Android上的另一个应用程序?

    我试图杀死我的另一个应用程序.但是这段代码无法杀死我的另一个应用程序.我知道杀死另一个应用程序是一个坏主意.但是我有一个学习的目的,并且我试图杀死人.我的代码部分: Button runningApp ...

  6. cefsharp执行完js代码后获取返回值问题

    CefSharp相关操作 Task<CefSharp.JavascriptResponse> t = mychrome.GetBrowser().MainFrame.EvaluateScr ...

  7. 01_Go语言基础学习_Golang语言特性、环境搭建、第一个Go程序、包

    1. Golang语言特性: 垃圾回收: 1.内存自动回收,再也不需要开发人员管理内存: 2.开发人员专注业务实现,降低了心智负担 : 3.只需要new分配内存,不需要释放 天然并发: 1.从语言层面 ...

  8. python定义函数后怎么输出_python中如何定义函数返回值

    返回值简介: 简单介绍print和return的区别,print仅仅是打印在控制台,而return则是将return后面的部分作为返回值作为函数的输出,可以用变量接走,继续使用该返回值做其它事. 函数 ...

  9. 用java编写一个故事的程序_使用Java怎么编写一个递归程序

    使用Java怎么编写一个递归程序 发布时间:2021-02-20 16:05:44 来源:亿速云 阅读:52 作者:Leah 这篇文章将为大家详细讲解有关使用Java怎么编写一个递归程序,文章内容质量 ...

最新文章

  1. mysql语句将日期转换为时间戳的方法
  2. 百度、头条、网易 Android 等社招面试题目
  3. 计算机系学生mac,大学生选择苹果电脑之后的经验之谈
  4. zhilizhili-ui 2016始动 开始做个样例站吧 (一)
  5. 如何下载Lucene.net源码
  6. Exchange管理之:使用Telnet发送邮件
  7. 方法range作用于对象worksheet时失败_VB.NET Excel操作类(获取工作簿列表和工作表列表及工作表对象)...
  8. Windows 环境安装 OS X Monaco 字体
  9. tf.matmul()和tf.multipy()的区别
  10. 易支付平台全网大汇总!总有一款适合你!
  11. 百度地图api 刷新地图_百度地图VS高德地图,谁更胜一筹?
  12. ALS算法介绍(协同过滤算法介绍)
  13. 关于路由器花生壳动态域名无法连接的解决方法
  14. 将 SVN Repositories 内部的下层目录,提升成为顶层 Repositories 的风险
  15. 七个问题透视百度智慧商业平台
  16. 万字吐血好文,一线分析师的4大总结。
  17. Mac M1 搭建虚拟机节点集群过程及软件分享
  18. EF的基本了解(一)
  19. 一文读懂物联网 MQTT 协议之实战篇
  20. Apache 与 CGI

热门文章

  1. TPC-C中跑赢Oracle的OceanBase,最近有何惊艳?
  2. 2019 年度程序员吸金榜:你排第几?
  3. kubernetes精华问答 | Swarm和K8S的共同点有哪些?
  4. AI 线上峰会 | 人工智能技术解析与实战
  5. Vue刷新当前页面几种方式
  6. OpenOffice+JodConverter实现Office文件到PDF的转换
  7. RuoYi-Vue 部署 Linux环境 若依前后端分离项目(jar包+nginx 多机版本)
  8. SpringBoot2 集成 xxl-job任务调度中心_参数传递
  9. SonarQube 质量配置,设置各个语言默认的扫描规则
  10. JavaScript-Map和Set