编译原理 - 关于C编译的疑问?

查看:150
本文介绍了编译原理 - 关于C编译的疑问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

写了一个C程序,一直没有看过编译后的代码,认为他是 01代码,理论上编译就是让计算机可识别的01代码。
问题:
为什么打开后却是这个样子的?(用的GCC编译)

解决方案

首先,你用gcc编译出的文件是ELF可执行文件
你用file命令查看一下你编译出的文件,就能发现这一点,比如说我这里随便编译了一个,file了一下:
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=de67fcb2b39d98dfea1f5b9d7377ed6f29d6172e, not stripped
既然是ELF文件,我们就用ELF工具来稍微分析一下它,关于ELF文件格式的详细分析,如果你有兴趣的话,可以去看一下这里
我们用readelf命令:readelf -h a.out,可以得到如下的结果:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
...

所以你可以看到,ELF文件是有固定格式的,而且除了可执行的部分以外,还包含了其他信息。


明确了上面这一点,我们从十六进制角度来分析一下这个文件,首先你要明确一点,计算机内没有文件是不用二进制表示的(这里是换算成了十六进制)

比方说,你用echo 01 > q这条命令,向q写入了0、1两个ASCII字符

我们用hexdump(一个十六进制查看工具)来看一下q的内容:

 % hexdump q
0000000 3130 000a
0000003

你可以看到ASCII中0是用0011 0000表示的,而1是用0011 0001表示的,对应十六进制正好是30、31。
而最后的0a对应二进制0000 1010,是ASCII中的换行符。
所以,计算机中所有文件都是用二进制表示的,包括文本文件,只是你查看文本文件的时候会用编码来解释二进制。
同样地,你用hexdump来查看一下刚才gcc编译生成的a.out,内容如下:

 hexdump a.out
0000000 457f 464c 0102 0001 0000 0000 0000 0000
0000010 0003 003e 0001 0000 0560 0000 0000 0000
0000020 0040 0000 0000 0000 19a0 0000 0000 0000
0000030 0000 0000 0040 0038 0009 0040 001e 001d
0000040 0006 0000 0005 0000 0040 0000 0000 0000
0000050 0040 0000 0000 0000 0040 0000 0000 0000
0000060 01f8 0000 0000 0000 01f8 0000 0000 0000
0000070 0008 0000 0000 0000 0003 0000 0004 0000
0000080 0238 0000 0000 0000 0238 0000 0000 0000
0000090 0238 0000 0000 0000 001c 0000 0000 0000
00000a0 001c 0000 0000 0000 0001 0000 0000 0000
00000b0 0001 0000 0005 0000 0000 0000 0000 0000
00000c0 0000 0000 0000 0000 0000 0000 0000 0000
...

这些用ASCII解释结果就是:

00000000   7F 45 4C 46  02 01 01 00  00 00 00 00  .ELF........
0000000C   00 00 00 00  03 00 3E 00  01 00 00 00  ......>.....
00000018   60 05 00 00  00 00 00 00  40 00 00 00  `.......@...
00000024   00 00 00 00  A0 19 00 00  00 00 00 00  ............
00000030   00 00 00 00  40 00 38 00  09 00 40 00  ....@.8...@.
0000003C   1E 00 1D 00  06 00 00 00  05 00 00 00  ............
00000048   40 00 00 00  00 00 00 00  40 00 00 00  @.......@...
00000054   00 00 00 00  40 00 00 00  00 00 00 00  ....@.......
00000060   F8 01 00 00  00 00 00 00  F8 01 00 00  ............
0000006C   00 00 00 00  08 00 00 00  00 00 00 00  ............
00000078   03 00 00 00  04 00 00 00  38 02 00 00  ........8...
00000084   00 00 00 00  38 02 00 00  00 00 00 00  ....8.......
00000090   38 02 00 00  00 00 00 00  1C 00 00 00  8...........
0000009C   00 00 00 00  1C 00 00 00  00 00 00 00  ............
000000A8   01 00 00 00  00 00 00 00  01 00 00 00  ............
000000B4   05 00 00 00  00 00 00 00  00 00 00 00  ............
000000C0   00 00 00 00  00 00 00 00  00 00 00 00  ............

另外,由于ELF文件有固定格式,所以你编译生成的不同ELF文件可能看起来有一部分相同。

这篇关于编译原理 - 关于C编译的疑问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆