计算机系统基础学习笔记(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 | 启动程序运行,程序在断点处停下 |
查看程序运行时的当前状态
程序的当前断点位置
含义:反映程序已经执行了哪些指令,下一步要执行哪一条指令。
eip寄存器:保存了下一条将要执行的指令的地址。ir 显示所有寄存器的内容 ir eip 只显示寄存器eip的内容 通用寄存器的内容:ir eax ebx ecx edx(或者ir)
存储器的单元内容:x/8xb Oxffd2bc
x命令用于查看储存单元的内容,后跟一些参数选项。
数据表示要显示的数据单元的个数。
x表示存储单元的内容,十六进制形式。
b表示要显示的储存单元的宽度,按字节显示(w:按4字节显示)
后面的数据表示要显示的存储单元的起始地址。x/8xb Oxffd2bc这条内容就是表示从Oxffd2bc地址单元开始,显示8个字节的存储单元内容,并用十六进制表示。
查看运行时的当前状态
说明: IA-32用栈来支持过程的嵌套调用,过程的入口参数,返回地址,被保存寄存器的值,被调用过程中的非静态局部变量等都会被保存在栈中。
栈帧信息:
当前栈帧范围: i r esp ebp (esp栈顶指针和ebp栈底指针 )当前栈帧字节数:y=R[ebp]-R[esp]+4 (不是命令,是计算方法)
显示当前栈帧内容:
x/yxb $esp
x/zxw $esp //z=y/4
继续执行下一条指令或语句
| 命令 | 作用 |
|---|---|
| si | 执行一条机器指令 |
| s | 执行一条c语句 |
退出调试
| 命令 | 作用 |
|---|---|
| quit | 退出GDB调试过程 |
本次给大家分享的内容就到这里啦,觉得还不错的点个赞支持一下小编,你的肯定就是小编前进的动力。另外如果想了解更多计算机专业的知识和技巧的,献上我的个人博客北徯,另外需要各种资料的童鞋,可以关注我的微信公众号北徯,免费的PPT模板,各种资料等你来领。

计算机系统基础学习笔记(1)-基本GCC,objdump,GBD命令的使用的更多相关文章
- 【C#编程基础学习笔记】4---Convert类型转换
2013/7/24 技术qq交流群:JavaDream:251572072 教程下载,在线交流:创梦IT社区:www.credream.com [C#编程基础学习笔记]4---Convert类型转换 ...
- 【C#编程基础学习笔记】6---变量的命名
2013/7/24 技术qq交流群:JavaDream:251572072 教程下载,在线交流:创梦IT社区:www.credream.com [C#编程基础学习笔记]6---变量的命名 ----- ...
- 1.C#基础学习笔记3---C#字符串(转义符和内存存储无关)
技术qq交流群:JavaDream:251572072 教程下载,在线交流:创梦IT社区:www.credream.com ------------------------------------- ...
- Java基础学习笔记总结
Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...
- Mysql数据库基础学习笔记
Mysql数据库基础学习笔记 1.mysql查看当前登录的账户名以及数据库 一.单表查询 1.创建数据库yuzly,创建表fruits 创建表 ) ) ,) NOT NULL,PRIMARY KEY( ...
- 0003.5-20180422-自动化第四章-python基础学习笔记--脚本
0003.5-20180422-自动化第四章-python基础学习笔记--脚本 1-shopping """ v = [ {"name": " ...
- Java基础学习笔记(一)
Java基础学习笔记(一) Hello World 基础代码学习 代码编写基础结构 class :类,一个类即一个java代码,形成一个class文件,写于每个代码的前端(注意无大写字母) XxxYy ...
- C#RabbitMQ基础学习笔记
RabbitMQ基础学习笔记(C#代码示例) 一.定义: MQ是MessageQueue,消息队列的简称(是流行的开源消息队列系统,利用erlang语言开发).MQ是一种应用程序对应用程序的通信方法. ...
- handlebars.js基础学习笔记
最近在帮学校做个课程网站,就有人推荐用jquery+ajax+handlebars做网站前端,刚接触发现挺高大上的,于是就把一些基础学习笔记记录下来啦. 1.引用文件: jquery.js文件下载:h ...
随机推荐
- Ansible Playbook 初识
Ansible Playbook 基本概述与使用案例 主机规划 添加用户账号 说明: 1. 运维人员使用的登录账号: 2. 所有的业务都放在 /app/ 下「yun用户的家目录」,避免业务数据乱放: ...
- GitHub 热点速览 Vol.13:近 40k star 计算机论文项目再霸 GitHub Trending 榜
作者:HelloGitHub-小鱼干 摘要:"潮流是个轮回",这句话用来形容上周的 GitHub Trending 最贴切不过.无论是已经获得近 40k 的高星项目 Papers ...
- 1、Spark Core所处位置和主要职责
Spark组件是基于分布式资源引擎层(Yarn等)和分布式存储层(HDFS等)之上的一个组件,Spark本质上是一个计算引擎,负责计算的,根据不同计算场景划分出了SQL.Streaming.MLib. ...
- 微信APP支付-java后台实现
不说废话,直接上代码 先是工具类(注意签名时要排序): import java.io.BufferedReader; import java.io.ByteArrayInputStream; impo ...
- 3D画廊
3D画廊 之前我都是写的学习的内容,我在写这些教程时遇到有趣的炫酷的小例子也会专门拿出来写一篇文章,今天就写一个酷炫的小例子,叫3D画廊,它是属于ViewPage的进阶版. 此项目下载地点:https ...
- Go深入学习之select
select的用法 1)select只能用于channel的操作(写入.读出),而switch则更通用一些 2)select的case是随机的,而switch里的case是顺序执行 3)select要 ...
- 【杂谈】SpringBoot为啥不用配置启动类
前言 在学习SparkJava.Vert.x等轻量级Web框架的时候,都遇到过打包问题,这两个框架打包的时候都需要添加额外的Maven配置,并指定启动类才能得到可执行的JAR包: 而springboo ...
- Jenkins集成时报错 hudson.remoting.Channel$CallSiteStackTrace: Remote call to JNLP4-connect connection from xxx.xxx.xxx.xxx/xxx.xxx.xxx.xxx:32034
Started by user test Running as SYSTEM Building remotely on home_windows (mbhCloud_UI_Test) in works ...
- linux下使用笔记本的相关设置
目录 无线连接 Wi-Fi 蓝牙 触摸板 电源管理 电源管理工具 电源相关行为的响应动作 按键和盖子的响应动作 电池低电量的响应动作 处理器调整 调频工具 关闭睿频 intel_pstate 休眠配置 ...
- 手动搭建I/O网络通信框架1:Socket和ServerSocket入门实战,实现单聊
资料:慕课网 第二章:手动搭建I/O网络通信框架2:Socket和ServerSocket入门实战,实现单聊 这个基础项目会作为BIO.NIO.AIO的一个前提,后面会有数篇博客会基于这个小项目利用B ...