计算机系统基础学习笔记(1)-基本GCC,objdump,GBD命令的使用,


基本GCC命令的使用

GCC是一套由GNU项目开发的编程语言编译器,可处理C语言、
C++、Fortran、Pascal、Objective-C、Java等等。GCC通常是 跨平台软件的编译器首选。gcc是GCC套件中的编译驱动程序名。

若计算机是x86-64位系统,为了编译成IA-32指令集,
则请先运行下列命令:

sudo apt-get install build-essential module-assistant 
sudo apt-get install gcc-multilib g++-multilib

接下来就以输出hello world这样一个简单的C语言程序hello.c来演示这个过程。

#include <stdio.h>
int main()
{
	printf("Hello,world\n");
	return 0;
}

hello.c这个源文件要经过预处理,编译,汇编,链接四个过程,最终生成可执行目标文件。示意图如下所示:


Linux中的gcc编译驱动程序可以实现上图过程的每一步,下面分别对其进行解释:

gcc –E hello.c –o hello.i 

对hello.c的程序进行预编译,预编译是对源程序以字符#开头的命令进行处理,对于这里来说就是将include后的.h文件内容嵌入到源程序文件中,预处理后的文件还是文本文件,用.i作扩展名,如下图所示:

gcc –S hello.i –o hello.s

对hello.i进行编译,生成一个汇编语言源程序,用.s作为扩展名,编译后的文件还是文本文件。

gcc –c hello.s –o hello.o

对hello.s文件进行汇编,生成一个可重定位目标文件,以.o作为扩展名,汇编后的文件是二进制文件。内容为0,1表示的机器指令,数据和其他信息。

gcc hello.o –o hello

此命令将多个可重定位的目标文件和标准库函数链接合成一个可执行文件。在这个例子中,链接将hello.o文件和标准库函数printf所在的可重定位目标模块printf.o进行链接,生成可执行目标文件hello。

运行可执行文件hello输入指令

./hello

上面是分步骤转换C语言程序到可执行目标文件,也可以用命令

gcc hello.c –o hello 

将hello.c直接编译成可执行目标文件hello。

在用gcc命令编译c程序时,会加入各种选择,例如以下命令:

gcc -o0 -m32 -g hello.c -o hello

比如加入-O0,塔表示编译时采用的优化级别,0表示不用编译优化,-m32这个选项表示编译成x86-32位的指令。如果计算机是64位架构的处理器,不加这个选项则会编译成x86-64位的指令集。-g表示带调试信息(单步调试必须加入)。

objdump命令的使用

目标文件都是由01序列的机器指令构成,数据和其他信息构成,用文本编辑器打不开,怎样才能看到目标文件的内容呢?答案是可以利用objdump工具来反汇编二进制的目标文件,对可重定位目标文件和可执行的目标文件都可以反汇编。
我们利用一个c程序来进行举例,程序名gdbtest.c。

#include "stdio.h"
int main()
{
	int x=3,y=5,z;
	z=x+y;
	printf("z=%d\n",z);
	return 0;
}

利用gcc命令可以分别编译为gdbtest.o的可重定位目标文件和gdbtest可执行目标文件。

gcc -E -g -m32 gdbtest.c -o gdbtest.i
gcc -S -g -m32 gdbtest.i -o gdbtest.s
gcc -c -g -m32 gdbtest.s -o gdbtest.o
gcc -o0 -m32 -g gdbtest.c -o gdbtest

建议在objdump命令中使用-S选项,并与gcc命令中的-g选项一起配合使用。

利用以下命令:

objdump –S gdbtest.o>gdbtesto.txt 
objdump –S gdbtest>gdbtest.txt

对这两个文件来进行反汇编,-S表示在反汇编后的内容中添加源代码,方便理解C语言源程序与IA-32机器级指令之间的对应关系。'>'这个符号表示将反汇编后的内容保存在文件中,在这里是保存为文本文件,为了防止内容太多输出到屏幕上不方便阅读。

gdbtest.o的可重定位目标文件的反汇编文件内容如下:

可执行目标文件的反汇编内容:

可重定位目标文件和可执行目标文件的一个很重要的区别就是指令的地址是不是从0地址开始。可重定位目标文件是完成一个子任务的独立模块,所以每个模块的地址都是从0地址开始,然而可执行目标文件中的的指令和数据都有一个确定的地址,是安装操作系统给定的储存器地址映射分配,也是在调试步骤中可以看到的地址。不是内存的物理地址,是虚拟地址。

GDB调试工具的使用

启动GDB调试工具

启动GDB调试工具,加载被调试的可执行文件。

命令 作用
1 gdb [可执行文件名] 启动GDB调试工具,并加载可执行文件
2 1.gdb
2. file [可执行文件名]
启动GDB调试工具
加载可执行文件

设置断点

设置断点,使程序运行到断点处停下来,方便查看程序运行的状态。

命令 作用
break main 在main函数的入口处设置断点
break gdbtest.c:3 在源程序gdbtest.c的di sa第3行处设置断点

启动程序运行

启动并运行已经加载的程序,程序在执行的设置的第一个断点会停下来。

命令 作用
run 启动程序运行,程序在断点处停下

查看程序运行时的当前状态

继续执行下一条指令或语句

命令 作用
si 执行一条机器指令
s 执行一条c语句

退出调试

命令 作用
quit 退出GDB调试过程

本次给大家分享的内容就到这里啦,觉得还不错的点个赞支持一下小编,你的肯定就是小编前进的动力。另外如果想了解更多计算机专业的知识和技巧的,献上我的个人博客北徯,另外需要各种资料的童鞋,可以关注我的微信公众号北徯,免费的PPT模板,各种资料等你来领。
北徯

相关内容

    暂无相关文章