编译器背后的故事

本文详述了GCC在Linux程序开发中的作用,包括预处理、编译、汇编和链接过程。通过实例展示了如何创建静态库和动态库,并比较了两者生成的可执行文件大小。同时,介绍了ELF文件格式、反汇编以及nasm汇编器的使用。此外,文章还提到了Linux终端常用的curses光标库及其关键函数,并简要回顾了古老的BBS终端程序。最后,给出了一个使用curses库实现的贪吃蛇游戏示例。
摘要由CSDN通过智能技术生成

编译器背后的故事

引入:gcc会对代码完成预处理,编译,汇编和链接四个步骤
gcc常用命令

一.用gcc生成静态库和动态库

1.按照书上的例子学习

1.1先创建执行程序所需要的文件,hello.c,main.c ,hello.h
1.2用gcc命令生成.o文件

静态库

1.3用ar命令生成静态libmyhello.a文件
1.4再链接.a文件和main.c文件生成可执行文件hello
在这里插入图片描述

动态库

1.5将hello.c文件编译生成.so共享动态库
1.6动态链接.so文件和main.c 文件生成可执行文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.自己编写程序练习静态库和动态库的步骤,并记录可执行文件的大小

2.1创建程序所需的x2x.c,x2y.c,try.c,X.h。
2.2按照上面的步骤生成静态链接库生成的可执行文件
2.3可执行文件的大小为8456b
在这里插入图片描述
2.4再用动态链接库生成可执行文件
2.5记录文件的大小为8352b
在这里插入图片描述

在这里插入图片描述
注:linux中查看文件大小的命令

stat try(文件名)

参考链接:

https://blog.csdn.net/longgeaisisi/article/details/90607642

3.使用静态库和动态库最后生成的可执行文件大小的比较

结论:动态链接生成的可执行文件要略小于静态链接生成的可执行文件

二、gcc不是一个人在战斗,gcc的集中用途,了解EFF文件格式,汇编语言格式

1.gcc的集中使用

创建一个简单的测试程序
在这里插入图片描述一步到位的编译指令是:
在这里插入图片描述

实质上,上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编 (Assembly)和连接(Linking)
1.1,预处理
在这里插入图片描述

gcc 的-E 选项,可以让编译器在预处理后停止,并输出预处理结果

1.2编译为汇编代码
在这里插入图片描述

gcc 的-S 选项,表示在程序编译期间,在生成汇编代码后,停止,-o 输出汇编代码文件

1.3汇编,将汇编代码文件生成目标文件
在这里插入图片描述

说明gas 汇编器负责将其编译为目标文件

1.4连接
在这里插入图片描述

说明gcc 连接器负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件
1.5执行文件
在这里插入图片描述

2.EFF文件格式

(1)分析 ELF 文件

1.ELF 文件的段
ELF 文件格式如下图所示,位于 ELF Header 和 Section Header Table 之间的都是段(Section)。一个典型的 ELF 文件包含下面几个段:
.text:已编译程序的指令代码段。
.rodata:ro 代表 read only,即只读数据(譬如常数 const)。
.data:已初始化的 C 程序全局变量和静态局部变量。
.bss:未初始化的 C 程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试。
在这里插入图片描述

可以使用 readelf -S 查看其各个 section 的信息如下:

readelf -S test

在这里插入图片描述
(2)反汇编EFF文件
由于 ELF 文件无法被当做普通文本文件打开,如果希望直接查看一个 ELF 文件包含的指令和数据,需要使用反汇编的方法。
使用 objdump -D 对hello文件进行反汇编如下:

objdump -D hello

在这里插入图片描述
也使用 objdump -S 将其反汇编并且将其 C 语言源代码混合显示出来。

gcc -o hello -g hello.c
objdump -S hello

3.nasm汇编编译器的运用

1.先安装nasm,在Linux环境下输入如下命令:

sudo apt-get install nasm

2.查看nasm是否安装成功,并开始用nasm进行编译

nasm -version

3.创建一个.asm文件,z在其中输入以下测试代码

; hello.asm 
section .data            ; 数据段声明
        msg db "Hello, world!", 0xA     ; 要输出的字符串
        len equ $ - msg                 ; 字串长度
section .text            ; 代码段声明
global _start            ; 指定入口函数
_start:                  ; 在屏幕上显示一个字符串
        mov edx, len     ; 参数三:字符串长度
        mov ecx, msg     ; 参数二:要显示的字符串
        mov ebx, 1       ; 参数一:文件描述符(stdout) 
        mov eax, 4       ; 系统调用号(sys_write) 
        int 0x80         ; 调用内核功能
                         ; 退出程序
        mov ebx, 0       ; 参数一:退出代码
        mov eax, 1       ; 系统调用号(sys_exit) 
        int 0x80         ; 调用内核功能

4.用nasm编译链接如下结果
在这里插入图片描述
5.记录可执行文件大小并比较
(1)nasm
在这里插入图片描述
(2)c代码编译
在这里插入图片描述
结论:从这里可以看出nasm汇编代码要比c代码文件小得多

三.程序背后的优秀代码库

1.Linux 系统中终端程序最常用的光标库(curses)

1)光标库的主要函数功能
curses函数库能够优化光标的移动并最小化需要对屏幕进行的刷新,从而也减少了必须向字符终端发送的字符数目。
2)几个基本函数名称及功能
(2.1)WINDOW *initscr(void)
initscr()函数通常是Curses程序第一个调用函数,用于判断终端类型和初始化Curses数据结构,同时也对终端进行一次刷新以清除屏幕,为以后的操作做准备。若执行时发生错误则在标准错误输出中输出错误信息并退出,正确执行就返回stdscr这一属于WINDOW类型的变量。
(2.2)int endwin(void)
每一个Curses程序在退出或要临时脱离Curses模式时都应调用endwin()函数。调用这个函数将恢复tty终端原来的状态,把光标移到屏幕的左下角.重置终端为正确的非虚拟模式。
(2.3)bool has_colors(void)
has_colors()例程无需参数。若终端能产生彩色,则返回TRUE﹔否则返回FALSE。程序员通过调用它去判断终端是否可以使用彩色。
(2.4)int use_default_colors(void)
use_default_colors例程是Curses库的一个扩展.它告诉Curses库把终端设置为缺省的前景/背景.缺省时前景为白色.背景为黑色.成功设置返回OK,否则返回ERR,两者都是整型数值。
(2.5)int init_pair(short pair,short f, short b)
init_pair()例程用于更改一个彩色对的定义。彩色对是Curses的一个概念,它用一个整型数值去标志一对前景/背景彩色。该例程有三个参数﹔彩色对数值pair,其范围从1到
COLOR_PAIRS-1;f(foreground指定前景彩色;b(background指定背景彩色。

2.以游客身份体验一下即将绝迹的远古时代的 BBS (一个用键盘光标控制的终端程序)

1.在 win10 系统中,“控制面板”–>“程序”—>“启用或关闭Windows功能”,启用 “telnet client” 和"适用于Linux的Windows子系统"(后面会使用)。
在这里插入图片描述

2.然后打开一个cmd命令行窗口,命令行输入

telnet bbs.newsmth.net

在这里插入图片描述

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

3.在Ubuntu中用 sudo apt-get install libncurses5-dev 安装curses库,请说明 头文件(比如curses.h)和库文件都被安装到哪些目录中

在这里插入图片描述
头文件(比如curses.h)和库文件的安装目录在哪?
curses函数库的头文件和库文件就被分别安装在/usr/include/和/usr/lib/下
在这里插入图片描述

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

1.创建一个snake.c的文件,将游戏代码复制进去

游戏代码:

http://www.linuxidc.com/Linux/2011-08/41375.htm

2.用curses编译链接生成可执行文件
在这里插入图片描述
:警告不用管它,直接运行生成的可执行文件
在这里插入图片描述

四.总结

学习到了静态链接库和动态链接库的区别,ar汇编编译器用法,光标库,还有以前的bbs,以及在Linux系统下的游戏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值