编译器背后的故事
实验环境: UBuntu18.04 桌面版
简单动态库与静态库的生成
简单静态库
1.编写三个C语言源文件:main1.c,x2x.c,x2y.c 一个C语言的头文件sub1.h。
//main1.c文件
#include"stdio.h"
#include"sub1.h"
int main(){
int a,b;
a=5;b=7;
printf("%f",x2x(a,b));
printf("%f",x2y(a,b));
return 0;
}
//sub1.c文件
float x2x(int a,int b)
{
return a*b;
}
//x2y.c文件
#include<stdio.h>
float c;
c=a*a+b*b;
return c;
//sub.h文件
#ifndef sub1_H
#define sub1_H
float x2x(int,int)
float x2y(int,int)
#endif //sub1_H
2.编译三个文件,生成三个.o文件
3.使用命令ar -crv file.a -o file.o 生成一个静态库,
由静态库生成的执行文件的大小
这里的静态库链接stdio.h时使用的是动态库
所以要使用 gcc -static main1.c sub1.a -o main2生成的可执行文件
简单动态库
将以上三个文件重新生成一个动态库
生成动态库并执行时发生错误
生成的动态库的文件大小
使用mv命令移动文件sub1.so时发生错误,再次移动添加sudo(使用临时管理员权限)移动成功,再次执行,成功
生成的执行文件大小
可以看出由静态库生成的可执行文件要远远大于由动态库生成的可执行文件
GCC编译工具的使用
安装nasm
sudo apt-get install nasm
然后编写一个hello.asm
; 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 ; 调用内核功能
nasm编译的过程:使用nasm -f elf64 hello.asm会编译hello.asm生成hello.o文件,在使用ld -s -o hello hello.o命令可以生成可执行文件。
使用size hello可以查看文件大小
hello.asm生成的可执行文件
hello.c生成的可执行文件
比较两个可执行文件的大小发现由hello.asm生成的可执行文件要比hello.c生成的可执行文件小得多。
用游客身份体验BBS
1.在 win10 系统中,“控制面板”–>“程序”—>“启用或关闭Windows功能”,启用 “telnet client” 和"适用于Linux的Windows子系统"。
2. 打开一个cmd命令行窗口,命令行输入 telnet bbs.newsmth.net,以游客身份体验一下即将绝迹的远古时代的 BBS (一个用键盘光标控制的终端程序)。
3.输入guest后一直按enter(回车)就好
curses库的安装与查找位置
1.使用sudo apt-get install libncurses5-dev命令安装curses库
2.使用whereis libcurses.*命令和whereis curses.h查找curses库中头文件与库的位置
curses库相关函数
小游戏贪吃蛇的gcc编译
1.新建一个文件夹,cd到该文件夹下,写入游戏源文件
2.游戏的编译过程中会产生一个警告,忽略就好
3.游戏生成的结果:"*“代表蛇,”@"代表食物
总结
gcc是一个非常强大的编译器,其中的很多东西都值得研究,curses库中也还有很多的东西需要亲自体验才能了解其中奥秘。若此次文章有不当之处,请多多交流。
参考文档:
贪吃蛇源文件
gcc编译背后的故事