第三次讲座盲点整理(编译与链接)——入口函数一定是main?
来源:互联网 发布:sqsx免费代理软件 编辑:程序博客网 时间:2024/06/15 00:01
自打从上大学C语言课的第一天起(不是第一天也是第二天了),我们就知道了这样一句话:一个C程序总是以main函数为入口,从main函数开始执行。昨晚刘欢学长为今天的讲座做铺垫,留下了几个问题,其中就有这样一个问题:C程序的入口是main函数?一定是main函数?
难不成不是?难不成这又会成为一个颠覆我三观的事实?!——函数入口可以不是main?!
带着疑惑,请教百度,对着屏幕瞠目结舌了半天,原来一个C程序的入口真的可以不是main。
先看这样一个程序:
#include <stdio.h>int junco(void){ printf("Fantastic!\n"); return 0;}显然,一眼就可以看出,这个程序没有main函数。一定不会被正常编译通过。
在用GCC进行编译时,会给出下列提示信息:
/usr/lib/gcc/i686-linux-gnu/4.7/../../../i386-linux-gnu/crt1.o:在函数‘_start’中:
(.text+0x18):对‘main’未定义的引用
collect2: 错误: ld 返回 1
可以看到错误信息提示,提到了一个“crt1.o”这个文件,其中crt是“Cruntime library”的缩写,其含义是“C运时库”。
C运行时库除了给我们提供必要的库函数调用(如memcpy、printf、malloc等)之外,它提供的另一个最重要的功能是为应用程序添加启动函数。C运行时库启动函数的主要功能为进行程序的初始化,对全局变量进行赋初值,加载用户程序的入口函数。
从给出的错误提示信息中还可以得知,在crt1.o中,有一个名为“_start”的函数。现在网上找到一份crt1.o的伪代码:
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;
从伪代码可以看出,在这个_start函数中,调用了main函数。那么我们可不可以用什么手段,去修改入口函数,把入口函数改成junco呢?
可以执行下面的命令:
gcc1.c -e junco -nostartfiles
其中-e选项为修改函数的入口地址,可惜在网上和man手册里都没有找到有关-e这个选项的解释,只搜索到了-E这个选项。问了好多人才明白原来-e指的就是entrance。这里把entrance指定为junco函数。-nostartfiles选项的作用是通知编译器不自动加入启动函数以及别的库级别的初始化,这样就不会调用到crt1.o中的_start函数。
此时,编译通过。可是执行程序,可以成功打印出Fantastic!字样,但是却会提示“段错误”
Fantastic!段错误 (核心已转储)
原来,在编译的时候加上了-nostartfiles这个选项的同时,使得最后的return语句不能正常执行。解决方案是,把程序最后的return语句改成exit语句,让exit语句来做最后的“善后工作”
#include <stdio.h>int junco(void){ printf("Fantastic!\n"); exit(0);}
这次则会正常执行, 没有任何错误!
- 第三次讲座盲点整理(编译与链接)——入口函数一定是main?
- 第三次讲座盲点整理(编译与链接)——课程设计里的密码原来就是虚设!
- 第一次讲座盲点整理(C类型与运算)
- 再议C语言(编译与链接)讲座整理
- 第二次讲座盲点整理(指针与数组补充、左值与右值)
- VS编译Qt时若主函数为wmain时出现链接错误,找不到main入口函数
- 代码逆向(一)——寻找main函数入口
- Python——程序入口main函数
- NASM源代码分析—入口函数main()(1)
- main是C/C++的入口函数么?
- 入口函数main
- mongodb - main 函数入口
- main函数入口
- Javascript基础知识盲点总结——函数
- 装载、链接与库——main函数的前世今生
- 第三次作业:《财务决策与分析》——财务报表是如何产生的(慕课组)
- main 函数的入口参数
- vc++ main系列入口函数
- 第11章Pig
- 图
- iPhone开发中的技巧整理
- POJ 2420 A Star not a Tree?(计算几何 多边形的费马点 模拟退火)
- 第11章Pig
- 第三次讲座盲点整理(编译与链接)——入口函数一定是main?
- 关于瀑布流
- OpenRisc-37-OpenRISC的CPU&core的整体架构分析
- 第11章Pig
- Ibatis 支持COLB 类型
- jq运用append和remove实现动态新增删除行
- UVa 11646 - Athletics Track
- 解决MySQLdb import Error问题
- ubuntu 命令