Linux下预处理,编译,汇编,链接过程及gdb的使用

时间:2022-04-18 00:55:53

在linux下,vim hello.c以后打开我们的命令模式,按i我们进入插入模式,然后编辑以下文本,编辑好以后按shift + ;,进入底行模式,输入wq保存退出(只输入q是退出并不保存)

#include<stdio.h>
#define MAOMAO "maomao\n"
//zhuhshi
/*zhushi*/
int main()
{
#pragma warning("normal err")
#if 0
printf("hello\n");
#else
printf(maomao);

#endif
}

一,预处理(进行宏替换)

[root@localhost a]# gcc hello.c -E -o hello.i
[root@localhost a]# vim test.i

-E 选项的作用是让gcc在预处理结束后停止编译过程。
-o 是指目标文件,“i”文件为已经预处理的c原始程序
预处理阶段的功能:
1)将所有的#define删除,并展开所有的宏定义。
2)处理所有的预处理指令,比如#if,#elif,#else,#endif,#ifdef。
3)处理#include预编译指令,将被包含的文件插入到预处理指令的位置,这个过程是递归的。
Linux下预处理,编译,汇编,链接过程及gdb的使用
4)过滤所有的注释”//”和/* */中的内容。
5)添加行号和文件名标识,比如#2”hello.c”2,以便于编译时编译器产生调试用的行号信息以及用于编译时产生编译错误或警告时能够显示行号。
6)保留所有的#pragma编译器指令,生成.i文件。

Linux下预处理,编译,汇编,链接过程及gdb的使用

二,编译(生成汇编)

[root@localhost a]# gcc hello.i -S -o hello.s
[root@localhost a]# vim hello.s

gcc首先检查代码的规范性,是否有语法错误,以确定代码实际要做的工作。
-S 选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
编译阶段的功能:
1)扫描,语法分析,语义分析,源代码优化,目标代码生成,目标代码优化;
2)生成汇编代码;
3)汇总符号;

4)生成.s文件

Linux下预处理,编译,汇编,链接过程及gdb的使用
为了便于更好的理解编译的整个过程,我们来画一个例子吧:
Linux下预处理,编译,汇编,链接过程及gdb的使用

三,汇编(生成机器可识别的代码)

汇编阶段功能:
1),形成符号表
2),汇编指令—>二进制指令
3),生成.o文件
[root@localhost a]# gcc hello.s -c -o hello.o
[root@localhost a]# vim test.o
汇编将hello.s翻译成下面的二进制机器语言指令,所以我们看不懂,把这些指令打包成一种叫做可重定位目标程序格式,并保存在.o文件中。

Linux下预处理,编译,汇编,链接过程及gdb的使用

四,链接

链接:
将二进制机器语言指令转换为二进制的可执行程序。

[root@localhost a]# gcc hello.o -o a.out
[root@localhost a]# vim a.out

Linux下预处理,编译,汇编,链接过程及gdb的使用

[root@localhost a]# objdump -dS a.out >my.s
[root@localhost a]# vim my.s

接下来就可以看到a.out的文件内容
Linux下预处理,编译,汇编,链接过程及gdb的使用

五,运行

Linux下预处理,编译,汇编,链接过程及gdb的使用

附:我们可以通过file指令查看各个阶段的文件格式

[root@localhost a]# file hello.c
hello.c: ASCII text
[root@localhost a]# file hello.i
hello.i: ASCII C program text
[root@localhost a]# file hello.s
hello.s: ASCII assembler program text

六,gdb使用

我们来写一个计算两个数多少位比特位不同的程序。
Linux下预处理,编译,汇编,链接过程及gdb的使用
先来看看运行结果:
Linux下预处理,编译,汇编,链接过程及gdb的使用
下面使用gbb调试:
注:linux gcc/g++出来的二进制程序,默认是release模式,调试时须在源代码生成二进制程序时加上-g选项。

1)启动调试:gdb 可执行程序名
Linux下预处理,编译,汇编,链接过程及gdb的使用
2)查看代码: l(list)
Linux下预处理,编译,汇编,链接过程及gdb的使用
3)设置当前文件断点: b (break) 行号
删除断点:d(delect)
4) 查看断点信息:i b (info break)
4)从开始连续而非单步执行程序:r(run)

Linux下预处理,编译,汇编,链接过程及gdb的使用
其余gdb调试指令总结:
(1)启动gdb:gdb 可执行程序名
(2)查看代码:l
l 查看当前文件
l 目标文件.c:行号 —直接显示目标文件的目标行
l 目标文件.c 函数名—显示目标文件的函数
(3)设置追踪变量 diaplay 变量名
取消追踪变量 undispiay 编号
(4)开始执行gdb调试 start
执行一步操作 n
继续执行 c
执行多步,直接停在断点处 x
(5)变量
查看变量 的值 p 变量名
查看变量的类型 whatis 变量
修改变量的值 set var
(6)退出gdb quit