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库和ttty

endwin()						关闭curses并重置tty

move(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 运行该程序
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值