为什么c程序里一定要写main函数
一、 学习过程
编写程序f.c:
对其进行编译,正常通过,再对其进行连接,出现错误:
显示的出错信息为:
翻译成中文是:在c0s模块没有定义符号’_main’。
那么这个错误信息可能与文件c0s.obj有关。那么是什么原因导致编译出错呢?
既然已经将程序编译成了obj文件,那么用之前我们经常使用的link.exe能否将它连接呢?结果是可以的:
用debug查看f.exe:
程序是从06fb:0到06fb:001c,一共29个字节。但是整个程序的代码有541字节:
执行最后一条ret指令,返回到b800处:
查看该地址的上一条指令:
发现上一条指令是push ds,不是跳转指令,所f.exe没有正确返回.
由上图知f函数的偏移地址是0.
编写程序m.c:
对m.c进行编译连接,这一次连接没有出现错误。
用debug查看m.exe,发现代码还是在1fa处:
程序是从06fb:01fa到06fb:0216,一共29个字节。但是整个程序的代码有4.19KB:
程序返回06fb:011d,查看该地址之前的代码:
发现上一条指令是call 01fa,即跳转到主程序所在代码段,所以程序的返回是正确的。
观察两个程序的汇编代码发现:
(1)f.exe的偏移地址为0,在debug中直接用u命令就可看到,而m.exe的偏移地址为1fa,在debug中用u命令查看到的不是main函数中的代码。
(2)f.exe有没有被调用,所以函数返回是错误的,m.exe被调用了,所以函数的返回是正确的。
由上图知:对main函数进行调用的指令地址为06fb:011a,整个m.exe程序返回的指令是:
我们发现,对main函数进行调用的指令和程序返回的指令都不是我们所写的语句,而是编译或连接过程中提供的。
没有main函数时,Tc里出现连接错误,提示c0s.obj里的main是没有定义的,而没有c0s.exe就无法对程序进行连接,那么有可能tc是把c0s.obj或者它的一部分与m.exe
一起进行连接生成exe文件。而且对main函数进行调用的指令和程序返回的指令应该就是c0s.obj所提供的。那么我们要对c0s.obj进行研究,可以用link.exe对它进行连接,再用debug查看汇编代码。发现虽然link提示错误,但是还是生成了c0s.exe文件:
用debug查看c0s.exe和m.exe发现连个程序的代码非常相似,那么m.exe中调用了main函数,c0s.exe中调用了什么呢?
可以看到,c0s.exe中本来应该指向main函数段的地方因为找不到main函数,所以指向了下一条语句。还有这两段程序中call的程序段地址都不一样。
所以C语言编程一定要写main函数是因为c0s.obj连接后要调用main函数执行其功能,如果我们把main函数写成其他的函数,c0s.obj里的代码不会识别。如f.exe虽然可以由link.exe连接,但是不会被调用,而是直接执行其中的内容,造成返回错误。而书上说c0s.obj的作用是:在程序开始运行,进行相关初始化,再调用main函数,返回后进行相关的资源释放,环境恢复等工作,再将程序返回。那么如果我们改写c0s.obj使其调用的不是main函数而是其他函数,编程时就可以不写main函数了。
编写c0s.txt:
用masm编译成obj文件,覆盖原来的c0s.obj文件。
将f.c重新编译连接,这次的连接成功了。
用debug查看f.exe:
发现我们重写的c0s.obj的内容出现在程序中,f函数的偏移地址为0012,且返回正确。f.exe可以正确运行。
编写新的程序f.c:
这里的实现原理与上一篇的最后一个程序相同,不同的是将main函数换成了f函数,因为我们重写了c0s.obj,所以同样可以执行。但是为什么前者是用malloc函数开辟了20个字节的空间,而后者是直接赋0呢?我觉得应为是200:0的安全空间,所以可以直接使用,但是如果在比较复杂的程序中或者空间比较紧张,则要先开辟空间,这样比较安全。
二、 解决的问题
(1) c0s.obj文件的作用:在程序开始运行,进行相关初始化,再调用main函数,返回后进行相关的资源释放,环境恢复等工作,再将程序返回。
(2) 可否用其他函数代替main函数?
答:可以,但是要修改c0s.obj文件。
三、 未解决的问题
(1) link.exe是集成了c0s.obj、emu.obj等所有编译需要的文件吗?
(2) 如果不修改c0s.obj,要将f.c编译成功还需要哪些文件?
四、 学习感想
我们在解决复杂的问题时,要把它分解成一个一个小问题来解决。这次的研究是书上提出了问题来帮助我们理解和思考,但是真正解决问题时是没有人来帮助我们划分问题、提出问题的。所以在平时的学习中,我们要多督促自己养成好的思考的习惯。
转载于:https://www.cnblogs.com/stormpeach/p/4321526.html
为什么c程序里一定要写main函数相关推荐
- linux 为什么 c语言,为什么C程序里一定要写main函数
为什么C程序里一定要写main函数 一. 学习过程 编写程序f.c: 对其进行编译,正常通过,再对其进行连接,出现错误: 显示的出错信息为: 翻译成中文是:在c0s模块没有定义符号'_main'. 那 ...
- Python 为什么没有 main 函数?为什么我不推荐写 main 函数?
毫无疑问 Python 中没有所谓的 main 入口函数,但是网上经常看到一些文章提"Python 的 main 函数"."建议写 main 函数"-- 有些人 ...
- c语言规定对于一个正常运行的c程序,下列叙述中正确的是,对于一个正常运行的C语言程序,以下叙述中正确的是()。A.程序的执行总是从main函数开始,在main函...
对于一个正常运行的C语言程序,以下叙述中正确的是().A.程序的执行总是从main函数开始,在main函 更多相关问题 某35 kV配电装置室长70m,按规程规定宜设置出口个数.( ) 加工中心的主要 ...
- c语言的程序运行原理图,C语言main函数的原理详解
C语言标准在一开始(C90标准 5.1.2条),就规定了程序的执行环境.对于没有操作系统的环境来说,C程序的入口函数是什么都可以(也就是说的在单片机的C程序里,或者在操作系统的底层代码的C入口处,不需 ...
- C语言必须写main函数?最简单的 Hello world 你其实一点都不懂!
我们在刚写程序的时候,第一个都是 hello world,而在这里,完整的代码就是: 我们打眼一看,其实很简单,就是引入头文件,写一个主函数,然后输出一句话,但是当我们编译出来ELF的时候,我们使用工 ...
- [置顶] Embedded Server:像写main函数一样写Web Server
1.传统的JEE Web Server 传统的JEE中,如果我们想要部署一个Web Application,我们需要首先安装一个Container Server,如JBoss,WebLogic,Tom ...
- C++程序设计基础(8)main函数
注:读<程序员面试笔记>笔记总结 1.知识点 (2)main函数的形式 1 //first type 2 int main() 3 //second type 4 int main(int ...
- 怎样在vrep child scirpt里定义自己写的函数
举例说明: myFunction=function(a,b)return a+b endif (sim_call_type==sim_childscriptcall_initialization) t ...
- python程序一定要有主函数_Python 没有main函数的原因
毫无疑问 Python 中没有所谓的 main 入口函数,但是网上经常看到一些文章提"Python 的 main 函数"."建议写 main 函数"-- 有些人 ...
最新文章
- ML_SVM的菜鸟实现
- POJ 1704 Georgia and Bob (Nim游戏变形)
- converter 迁移xen server 上的虚拟机 到 wmware esxi
- 向uliweb中添加查找配置项功能
- java 判断水仙花_Java实现判断水仙花数
- 产品工作中保持饥饿感,保持拒绝90%以上的伪需求你就不会错过下一个微信
- 通过使用Byte Buddy,便捷地创建Java Agent
- python的变量对大小写并不敏感_Python编程基础02:Python基本语法
- Python稀疏矩阵运算库scipy.sparse用法精要
- 在全志平台调试博通的wifi驱动(类似ap6212)【转】
- 低功耗中的Isolation cells 和Level shifter cells
- 51单片机——LED点阵屏
- 中学计算机兴趣小组 计划,陵口中学科技兴趣小组工作计划
- 读《张一鸣:我的大学四年收获及工作感悟》有感
- mahout安装和测试
- (memcpy,memmove...)内存函数还不会??别怕,我来助你一臂之力
- html中,table 的cellpadding cellspacing 属性失效
- DM9006 linux driver
- mysql string agg_如何从string_agg()中以正确的顺序得到结果
- Apache Ratis中的multi-raft实现原理