学习任务:
1.用gcc生成静态库和动态库.
2.静态库.a与.so库文件的生成与使用
3.学习gcc编译工具集中各软件的用途,了解EFF文件格式,汇编语言格式。
4.请在ubuntu中下载安装nasm,对示例代码“hello.asm”编译生成可执行程序
5.
一.静态库和动态库的运行及使用
1.编写程序
用nano编写两个功能函数和一个主函数
main1.c
#include<stdio.h>
int main()
{
int a=3 , b=2;
printf("%d\n ", x2x(a,b));
printf("%d\n", x2y(a,b));
return 0;
}
sub1.c
#include<stdio.h>
float x2x(int a,int b){
int c;
c=a+b;
return c;
}
sub2.c
#include<stdio.h>
float x2y(int a, int b)
{
return a-b;
}
2.生成.o文件
gcc编译为3个.o 目标文件
3.静态库文件的生成及链接执行
(1)由.o文件创建静态库
静态库文件名的命名规范是以 lib 为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将 创建的静态库名为 sub,则静态库文件名就是 libsub.a。在创建和使用静态库时, 需要注意这点。创建静态库用 ar 命令。在系统提示符下键入以下命令将创建静态库文件 libsub.a。
输入如下指令,并输入ls指令查看结果如图
ar -crv libsub.a sub1.o sub2.o
(2)在程序中使用静态库
在程序中生成静态库有以下三种方法:
方法一: gcc -o hello main.c -L. –lmyhello 自定义的库时,main.c 还可放在-L.和 –lmyhello 之间,但是不能放在它俩之后,否则会提 示 myhello 没定义,但是是系统的库时,如 g++ -o main(-L/usr/lib) -lpthread main.cpp 就不出错。
方法二: #gcc main.c libsub.a -o hello
方法三: 先生成 main.o: gcc -c main.c 再生成可执行文件: gcc -o hello main.o libsub.a
动态库连接时也可以这样做。
在用主程序使用所生成的静态库(hello)
4.动态库文件的生成及链接执行
(1)由.o 文件创建动态库文件
动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀 lib,但其 文件扩展名为.so。例如:我们将创建的动态库名为 myhello,则动态库文件名就是 libmyhello.so。
输入以下命令,并使用ls命令查看目录如图
gcc -shared -fPIC -o libmyhello.so sub1.o sub2.o (-o 不可少)
(2)在程序中使用动态库
先运行 gcc 命令生成目标文件,再运行它看看结果。
gcc -o hello main.c -L. -lmyhello
会显示如下内容:./hello: error while loading shared libraries: libmyhello.so: cannot open shar ed object file: No such file or directory
解决方法:将文件 libmyhello.so 移动到目录/usr/lib 中
二.GCC的运行
- gcc的编译过程
步骤: 预处理->编译->汇编->链接
示例:
#include <stdio.h>
int main(void)
{
printf("Hello World! \n");
return 0;
}
(1)预编译
将源文件 hello.c 文件预处理生成 hello.i
(2)编译
将预处理生成的 hello.i 文件编译生成汇编程序 hello.s
(3)汇编
将编译生成的 hello.s 文件汇编生成目标文件 hello.o
(4)链接
分为静态链接和动态链接,生成可执行文件
2.EFF文件格式,汇编语言格式
(1) ELF 文件的段
ELF 文件格式如下图所示,位于 ELF Header 和 Section Header Table 之间的都是段(Section)
一个典型的 ELF 文件包含下面几个段:
text:已编译程序的指令代码段。 .
rodata:ro 代表 read only,即只读数据(譬如常数 const)。
data:已初始化的 C 程序全局变量和静态局部变量。
bss:未初始化的 C 程序全局变量和静态局部变量。 .
debug:调试符号表,调试器用此段的信息帮助调试。
(2)反汇编 ELF
由于 ELF 文件无法被当做普通文本文件打开,如果希望直接查看一个 ELF 文件包 含的指令和数据,需要使用反汇编的方法。
使用 objdump -D 对其进行反汇编
三.nasm的安装使用
1.安装
(1)方法一:
(2)方法二:
博主使用的本方法
sudo apt install nasm
然后输入以下指令检查是否安装完成:
2.使用nasm对示例代码“hello.asm”编译生成可执行程序
创建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 ; 调用内核功能
- 编译输出
四.Linux中的第三方库函数
1.了解Linux 系统中终端程序最常用的光标库(curses)
(1)initscr(): initscr() 是一般 curses 程式必须先呼叫的函数, 一但这个函数被呼叫之后,系统将根据终端机的形态并启动 curses 模式
(2) endwin(): curses 通常以呼叫 endwin() 来结束程式.endwin() 可用来关闭curses 模式, 或是暂时的跳离 curses 模式
(3)refresh(): refresh() 为curses 最常呼叫的一个函式
(4)move(y,x): 将游标移动至 x,y 的
(5)echochar(ch)/addch(ch):显示某个字元
- 安装curses库
在Ubuntu中用 sudo apt-get install libncurses5-dev
可以查看头文件所在目录
3.以游客身份体验一下即将绝迹的远古时代的 BBS (一个用键盘光标控制的终端程序)
在 win10 系统中,“控制面板”–>“程序”—>“启用或关闭Windows功能”,启用 “telnet client” 和"适用于Linux的Windows子系统"(后面会使用)。
然后打开一个cmd命令行窗口,命令行输入 telnet bbs.newsmth.net
4…Linux 环境下C语言编译实现一些游戏
访问以下链接即可学习编写
Linux下编写贪吃蛇游戏
弹球游戏
示例贪吃蛇游戏: