关于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编译的疑问? 的全部内容, 来源链接: utcz.com/p/194068.html

回到顶部