GCC编译器背后的故事
发布日期:2021-11-03 09:33:17 浏览次数:2 分类:技术文章

本文共 2527 字,大约阅读时间需要 8 分钟。

GCC编译器背后的故事

一、可执行程序是如何被组装的

1、用 gcc 生成 .a 静态库和 .so动态库

第 1 步:编辑生成例子程序 hello.h、hello.c 和 main.c。

先创建一个作业目录,保存本次练习的文件。
在这里插入图片描述
然后用 vim、nano 或 gedit 等文本编辑器编辑生成所需要的 3 个文件。
hello.c是函数库的源程序,其中包含公用函数 hello,该函数将在屏幕上输出"Hello
XXX!"。hello.h(见程序 1)为该函数库的头文件。main.c为测试库文件的主程序,
在主程序中调用了公用函数 hello。

程序 1: hello.h

在这里插入图片描述
程序 2: hello.c
在这里插入图片描述
程序 3: main.c
在这里插入图片描述

第 2 步:将 hello.c 编译成.o 文件。

无论静态库,还是动态库,都是由.o 文件创建的。因此,我们必须将源程序 hello.c 通过 g
cc 先编译成.o 文件。在系统提示符下键入以下命令得到 hello.o 文件。之后输出ls查看是否生成.o文件。
在这里插入图片描述
第 3 步:由.o 文件创建静态库
静态库文件名的命名规范是以 lib 为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将
创建的静态库名为 myhello,则静态库文件名就是 libmyhello.a。在创建和使用静态库时,
需要注意这点。创建静态库用 ar 命令。在系统提示符下键入以下命令将创建静态库文件
libmyhello.a。同时输入ls产看是否生成.a文件
在这里插入图片描述
第 4 步:在程序中使用静态库
输入gcc main.c libmyhello.a -o hello
输入./hello查看结果
在这里插入图片描述
删除静态库文件试试公用函数 hello 是否真的连接到目标文件 hello 中了。
在这里插入图片描述
程序照常运行,静态库中的公用函数已经连接到目标文件中了。

第 5 步:由.o 文件创建动态库文件

动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀 lib,但其
文件扩展名为.so。例如:我们将创建的动态库名为 myhello,则动态库文件名就是 libmyh
ello.so。用 gcc 来创建动态库。
在系统提示符下键入以下命令得到动态库文件 libmyhello.so。
输入ls查看是否生成.so文件
在这里插入图片描述
第 6 步:在程序中使用动态库
输入gcc main.c libmyhello.so -o hello
输入./hello查看结果
在这里插入图片描述
错误提示,找不到动态库文件 libmyhello.so。程序在运行时,会在/usr/lib 和/lib 等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。我们将文件 libmyhello.so 复制到目录/usr/lib 中。
移动文件后再次输入./hello查看结果。
在这里插入图片描述
成功了。这也进一步说明了动态库在程序运行时是需要的。

2、动态库和静态库生成可执行文件大小的对比

第 1 步:编辑生成程序 A.h、A.c、B.h、B.c、main.c

创建一个 test2文件夹,并在该文件夹中分别创建子程序 A.h、A.c、B.h、B.c、main.c
在这里插入图片描述
程序1 A.h
在这里插入图片描述
程序2 A.c
在这里插入图片描述
程序3 B.h
在这里插入图片描述
程序4 B.c
在这里插入图片描述
程序5 main.c
在这里插入图片描述
第二步:用静态库文件进行链接,生成可执行文件
将 A.c,B.c 编译成 .o文件
在这里插入图片描述
用.o文件创建静态库
在这里插入图片描述

在程序中使用静态库

在这里插入图片描述
第三步:用动态库文件进行链接,生成可执行文件
用.o文件创建动态库
在这里插入图片描述
在程序中使用动态库
在这里插入图片描述
两个可执行文件大小的比较
按上面的方法由静态库链接生成的可执行文件,不是完全由静态库链接生成的,因为在 main.c 中调用的 stdio.h 是由动态链接的,所以需要重新由静态库链接生成一个可执行文件,否则可能将会出现静态库生成的可执行文件小于动态库生成的。

size:用于查看文件大小

ldd:查看链接了那些动态库
在这里插入图片描述

二、gcc编译器的编译

1、创建一个 test0 文件夹,并在该文件夹中创建一个 hello.c 程序

在这里插入图片描述
hello.c文件内容

在这里插入图片描述

2、程序的编译过程
预编译(将源文件 hello.c 文件预处理生成 hello.i)
在这里插入图片描述
编译(将预处理生成的 hello.i 文件编译生成汇编程序 hello.s)
在这里插入图片描述
汇编(将编译生成的 hello.s 文件汇编生成目标文件 hello.o)
在这里插入图片描述
链接(分为静态链接和动态链接,生成可执行文件)
在这里插入图片描述
在这里插入图片描述

4、在ubuntu中下载安装nasm,对示例汇编代码“hello.asm”编译生成可执行程序,并与上述用C代码的编译生成的可执行程序大小进行对比。

编译汇编 hello.asm文件,并于C代码的编译生成的程序大小进行对比

在这里插入图片描述

编译(elf 默认为32位)并链接:

在这里插入图片描述
汇编与C代码的编译生成的可执行程序大小对比
在这里插入图片描述

三、了解实际程序是如何借助第三方库函数完成代码设计

光标库(curses)的主要函数功能

nitscr()	 				初始化curses库和tttyendwin()						关闭curses并重置ttymove(y,x)			 	将光标移动至x,y的位置getyx(win,y,x)	得到目标游标的位置clear()and erase()	将整个屏幕清楚

echochar(ch) 显示某个字元

1、体验一下即将绝迹的远古时代的 BBS

在 win10 系统中,“控制面板”–>“程序”—>“启用或关闭Windows功能”,启用 “telnet client” 和"适用于Linux的Windows子系统"(后面会使用)。 然后打开一个cmd命令行窗口,命令行输入 telnet bbs.newsmth.net,以游客身份体验一下即将绝迹的远古时代的 BBS (一个用键盘光标控制的终端程序)。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2、Linux 环境下C语言编译实现贪吃蛇游戏

安装curses库

在这里插入图片描述
通过 whereis 命令头文件和库文件被安装的目录
在这里插入图片描述
编译实现贪吃蛇游戏
代码参考(http://www.linuxidc.com/Linux/2011-08/41375.htm)

在这里插入图片描述

./mysnake 运行该程序

在这里插入图片描述

转载地址:https://blog.csdn.net/weixin_51118019/article/details/109102956 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:计算机网络实验
下一篇:Proteus下简单51程序设计和仿真

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月10日 09时43分56秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

【Leetcode刷题篇/面试篇】经典动态规划-买卖股票问题总结汇总 2019-04-26
【Java锁体系】五、隐式锁和显式锁的区别(Synchronized和Lock的区别) 2019-04-26
【Java锁体系】六、AQS原理分析(AbstractQueuedSynchronizer实现分析) 2019-04-26
【Java锁体系】七、JMM内存模型详解 2019-04-26
【Java锁体系】八、MESI缓存一致性协议讲解 2019-04-26
【面试篇】Java锁体系 2019-04-26
【面试篇】JVM体系 2019-04-26
【Leetcode刷题篇】leetcode406 根据身高重建队列 2019-04-26
【Leetcode刷题篇】leetcode581 最短无序连续子数组 2019-04-26
【Leetcode刷题篇】leetcode538 把二叉搜索树转换为累加树 2021-06-29
【多线程与高并发】线程的优先级是怎么回事? 2021-06-29
【多线程与高并发】Java守护线程是什么?什么是Java的守护线程? 2021-06-29
【Leetcode刷题篇/面试篇】-前缀树(Trie) 2021-06-29
【Leetcode刷题篇】leetcode337 打家劫舍III 2021-06-29
【Leetcode刷题篇】leetcode4 寻找两个正序数组的中位数 2021-06-29
【Leetcode刷题篇】leetcode316 去除重复字母 2021-06-29
【Leetcode刷题篇】leetcode1081 不同字符的最小子序列 2021-06-29
【面试篇】Java网络编程与IO流体系 2021-06-29
【大话Mysql面试】-Mysql的索引为什么要使用B+树,而不是B树,红黑树等之类? 2021-06-29
【大话Mysql面试】-如何通俗易懂的了解Mysql的索引最左前缀匹配原则 2021-06-29