计算机系统——程序转换(objdump)

文章目录

  • **计算机系统——程序转换(objdump工具)**
    • **🚀指令**
    • **🚀程序转换**
      • **预处理**
      • **编译**
      • **汇编**
      • **链接**

计算机系统——程序转换(objdump工具)

🚀🚀接下来我们就来介绍一下有关我们的反汇编工具——objdump的介绍,但是我们不会局限于objdump的使用,我们会详细来介绍程序的转换过程,希望能让大家对于一个C语言程序从编写出来到执行这一整个过程能有一个基本的认识。


🚀指令

🚀🚀首先,我们要来介绍一下有关指令的相关知识,计算机中的指令有微指令、机器指令和伪(宏)指令之分。

  • 机器指令:处于硬件和软件的交界面
  • 微指令:微程序级命令,属于硬件范畴
  • 伪指令:由若干机器指令组成的指令序列,属于软件范畴
  • 汇编指令:机器指令的汇编表示形式,即符号表示

🚀🚀而我们的机器指令和汇编指令一一对应,它们都与具体机器结构有关,都属于机器级指令,我们以后的介绍都会基于机器级指令来介绍。


🚀程序转换

🚀🚀接下来我们就来介绍一下有关程序转换的相关知识,主要涉及到预处理、汇编、编译和链接这四个过程,接下来我们会对各个部分进行一个介绍。

在这里插入图片描述

预处理

🚀🚀预处理到底是个说明东西呢?其实很简单,就是我们写的C语言程序中的#开头的语句,比如命令指定的文件和用#define声明指定的宏,就是在预处理部分去处理的。

#include 
#define MAX 80

🚀🚀而想要完成对程序的预处理,我们就需要使用以下的命令去实现:

gcc -E -g -m32 a.c -o a.i  # 这边是使用32位去编译的,在这之前需要在Linux中输入以下命令
sudo apt-get install gcc-multilib # 安装32位编译器

🚀🚀这个时候,我们就生成了一个预处理结果文件a.i。


编译

🚀🚀编译的话,其实主要的作用就是把我们刚刚的预处理文件转换为汇编语言程序,需要用到下面的语句去操作。

gcc -S -g gdbtest.i -o gdbtest.s

🚀🚀这样我们就生成了一个汇编语言程序,如下所示。

	.file 1 "a.c".loc 1 2 11.cfi_startprocleal	4(%esp), %ecx.cfi_def_cfa 1, 0andl	$-16, %esppushl	-4(%ecx)pushl	%ebpmovl	%esp, %ebp.cfi_escape 0x10,0x5,0x2,0x75,0pushl	%ebxpushl	%ecx.cfi_escape 0xf,0x3,0x75,0x78,0x6.cfi_escape 0x10,0x3,0x2,0x75,0x7csubl	$16, %espcall	__x86.get_pc_thunk.axaddl	$_GLOBAL_OFFSET_TABLE_, %eax.loc 1 3 9movl	$3, -20(%ebp).loc 1 3 16movl	$5, -16(%ebp)

🚀🚀这里需要注意的是,我们生成的是AT&T格式的汇编语言,而不是我们的Intel格式的汇编语言,不过理解起来还是比较简单的,就是看的特别不舒服,个人不太喜欢AT&T格式的。


汇编

🚀🚀接下来就是我们的汇编阶段,他的作用就是由汇编程序将汇编语言源程序文件转换为可重定位的机器语言目标代码文件,使用的语句如下:

gcc -c –g a.s -o a.o

🚀🚀到了这一步,我们就需要使用我们的objdump工具了,主要的作用就是反汇编,把我们刚刚生成的重定位的机器语言目标代码文件(.o文件)变成汇编代码,使用的方法如下所示:

objdump –S a.o>a.txt 

🚀🚀这个-S 的意思是保留C语句, >的意思是把内容放到a.txt文件里面去。

🚀🚀结果如下所示:

00000000 
: #include int main(){0: 8d 4c 24 04 lea 0x4(%esp),%ecx4: 83 e4 f0 and $0xfffffff0,%esp7: ff 71 fc push -0x4(%ecx)a: 55 push %ebpb: 89 e5 mov %esp,%ebpd: 53 push %ebxe: 51 push %ecxf: 83 ec 10 sub $0x10,%esp12: e8 fc ff ff ff call 13 17: 05 01 00 00 00 add $0x1,%eaxint x = 3, y = 5, z;1c: c7 45 ec 03 00 00 00 movl $0x3,-0x14(%ebp)23: c7 45 f0 05 00 00 00 movl $0x5,-0x10(%ebp)z = x + y;2a: 8b 4d ec mov -0x14(%ebp),%ecx2d: 8b 55 f0 mov -0x10(%ebp),%edx30: 01 ca add %ecx,%edx32: 89 55 f4 mov %edx,-0xc(%ebp)printf("z = %d\n",z);35: 83 ec 08 sub $0x8,%esp38: ff 75 f4 push -0xc(%ebp)3b: 8d 90 00 00 00 00 lea 0x0(%eax),%edx

链接

🚀🚀接下来就是最后一步链接:由链接器将多个可重定位的机器语言目标文件以及库例程(如printf()库函数)链接起来,生成最终的可执行目标文件。使用的命令如下所示:

gcc -O1 -g a.c -o a

🚀🚀值得我们注意的是O1表示一级优化,-O2为二级优化,选项-o指出输出文件名

🚀🚀然后在这一步,我们也可以使用反汇编工具,命令如下所示:

objdump –S a>a.txt

🚀🚀运行结果如下所示:

0000119d 
: #include int main(){119d: 8d 4c 24 04 lea 0x4(%esp),%ecx11a1: 83 e4 f0 and $0xfffffff0,%esp11a4: ff 71 fc push -0x4(%ecx)11a7: 55 push %ebp11a8: 89 e5 mov %esp,%ebp11aa: 53 push %ebx11ab: 51 push %ecx11ac: 83 ec 10 sub $0x10,%esp11af: e8 44 00 00 00 call 11f8 <__x86.get_pc_thunk.ax>11b4: 05 24 2e 00 00 add $0x2e24,%eaxint x = 3, y = 5, z;11b9: c7 45 ec 03 00 00 00 movl $0x3,-0x14(%ebp)11c0: c7 45 f0 05 00 00 00 movl $0x5,-0x10(%ebp)z = x + y;11c7: 8b 4d ec mov -0x14(%ebp),%ecx11ca: 8b 55 f0 mov -0x10(%ebp),%edx11cd: 01 ca add %ecx,%edx11cf: 89 55 f4 mov %edx,-0xc(%ebp)printf("z = %d\n",z);11d2: 83 ec 08 sub $0x8,%esp11d5: ff 75 f4 push -0xc(%ebp)11d8: 8d 90 30 e0 ff ff lea -0x1fd0(%eax),%edx11de: 52 push %edx11df: 89 c3 mov %eax,%ebx11e1: e8 6a fe ff ff call 1050 11e6: 83 c4 10 add $0x10,%espreturn 0;11e9: b8 00 00 00 00 mov $0x0,%eax}

🚀🚀好了,关于程序转换和objdump工具就先介绍这么多,感谢大家的阅读了。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部