松江微网站建设,北京发布最新消息今天,深圳福田区,建筑公司简介模板免费下载我们在刚写程序的时候#xff0c;第一个都是 hello world#xff0c;而在这里#xff0c;完整的代码就是#xff1a;我们打眼一看#xff0c;其实很简单#xff0c;就是引入头文件#xff0c;写一个主函数#xff0c;然后输出一句话#xff0c;但是当我们编译出来ELF的… 我们在刚写程序的时候第一个都是 hello world而在这里完整的代码就是我们打眼一看其实很简单就是引入头文件写一个主函数然后输出一句话但是当我们编译出来ELF的时候我们使用工具readelf去查看下这里面的FUNC会发现多了很多方法。gcc相关工具链我经常用的是objdump 如果你想知道这个过程都处理了什么可以使用gcc -o hello hello.c -v这里的-v会输出过程信息这里截一部分大家看下这块要学习去GCC官方看下它的编译链接参数。Makefile文件可以使用 --just-print 进行调试。这里面的UND代表的是未定义未定义的这些方法会在加载器加载的时候补充进来。我们这里使用 IDA 来解析下这个输出ELF可以看到一个简单的信息。这里的Interpreter就是解析程序crtstuff.c这个就是给我们的运行环境做初始化。从这里我们就能看到其实我们的一个简单的程序也是五脏俱全的。既然它们的流程是系统加载进来然后初始化再到我们的main方法那么这个main方法肯定是可以变的。为什么这么说呢做过嵌入式开发的应该熟悉基本上都没有main函数一说直接从跳转入口开始跑就可以的。可以给任意函数指定成Enter也就是入口函数使用链接脚本就可以指定这块感兴趣的可以搜索gcc链接器参数。我们先简单做一个操作这样子来处理下。gcc -o hello hello.c -nostdlib我们来把这个库去掉看看会报哪些错误可以看到这里报了入口点找不到也就是_start 。https://my.oschina.net/saly/blog/130920 我们看下这里的参数介绍我们是用gcc -o hello hello.c -nostartfiles 把这个启动函数去掉然后我们自己实现一个。然后我们把文件修改成这里修改成exit 同时加上对应的库文件去掉return的原因是这时候不能返回需要清理返回去没人接这个系统中使用的是jmp你返回就找不到路了。然后这里已经没有main函数了直接用的_start这个属于覆盖的方式那么我们自己定义一个名字该怎么处理呢然后使用参数 gcc -o hello hello.c -nostartfiles -efuck_main -e这里就是 -enter的缩写代表指定入口通过这个操作最终我们实现了没有main函数的一个程序并且能够运行。今天在这里分享一个比较有用的命令在我们开发移植三方代码时候会遇见很多未定义包含错误链接失败这时候就需要定位我们的编译器参数echo main(){}|gcc -E -v - 这个可以看到详细的头文件链接库的引用信息当然我们可以使用--sysroot去指定同时配合着 -I -l 参数。到这里就完了吗必然不是我们看了如何修改入口函数我们如果想要在main前后做一些动作呢我们晓得的是动态库是有这个机制的我们静态可执行库也是有的具体是这里运行结果我们可以清晰的看到前后有了输出那么我们看下这个最终的elf这里找到after_main具体存放位置而这个对应位置的方法会在调用main之后进行遍历。所以这个是可以声明多个的。而关于退出还有个优雅的方式就是int atexit(void (*)(void));这个是一个设置退出方法然后在main结束后会进行执行这里就是注册很好理解。为什么有main函数主要是约定成俗你让别人用你的东西那必然要给他一个入口也就是你的系统跟他关联的那个定义main函数就是c语言开发大家约定的入口。但是在嵌入式开发当中因为整个的系统都是由我们处理从启动加载运行所以我们是可以不指定main函数可以自己来约定。好了第一讲就分享到这里下一节我们来说下c语言main函数的多种写法其中一个标准的写法是带有参数argv和argc下一节说下这个是如何查找定位的。~~ end not end ~~推荐阅读专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈关注公众号后台回复「1024」获取学习资料网盘链接。欢迎点赞关注转发在看您的每一次鼓励我都将铭记于心~