为什么机器语言不是a.out?

时间:2012-12-27 20:38:13

标签: c executable machine-language

我使用gcc编译以下程序并接收输出可执行文件a.out。:

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

当我执行cat a.out时,为什么文件处于“乱码”(这叫做什么?)而不是0和1的机器语言:

??????? H__PAGEZERO(__TEXT__text__TEXT?`??__stubs__TEXT 
P__unwind_info__TEXT]P]__eh_frame__TEXT?H??__DATA__program_vars [continued]

5 个答案:

答案 0 :(得分:10)

该文件为0和1,但是当您使用文本编辑器打开它时,这些位按字节分组,然后作为文本处理;)在Linux中,您可以尝试反汇编输出文件以确保它包含机器指令( x86架构):

objdump -D -mi386 a.out

示例输出:

1:  83 ec 08                sub    $0x8,%esp
4:  be 01 00 00 00          mov    $0x1,%esi
9:  bf 00 00 00 00          mov    $0x0,%edi 

第二列包含十六进制表示的0和1,第三列包含助记符汇编程序指令。

如果您想显示0和1,只需输入:

xxd -b a.out

示例输出:

 0000000: 01111111 01000101 01001100 01000110 00000010 00000001  .ELF..
 0000006: 00000001 00000000 00000000 00000000 00000000 00000000  ......

答案 1 :(得分:5)

这是某种executable file format。在Linux上,它可能是ELF,在Mac OS X上它可能是Mach-O,依此类推。甚至还有a.out格式,但它不再常见了。

它不仅仅是裸机指令 - 操作系统需要一些有关如何加载它的信息,附加到它的动态库等等。

答案 2 :(得分:1)

字符也由0和1组成,计算机无法知道差异。你要求它显示文件,但确实如此。

除了机器指令外,二进制文件还包含布局和可选的调试信息,这些信息可以是可读的字符串。

答案 3 :(得分:1)

a.out采用的格式是您正在使用的操作系统的加载程序可以理解。您看到的那些不同的文本是您期望的0和1的不同部分的标记。

?和`显示存在二进制不可打印数据的位置。

答案 4 :(得分:0)

目前Linux系统的典型格式是ELF。 ELF文件可能包含机器代码,您可以使用objdump实用程序检查它。

$ gcc main.c
$ objdump -d -j .text a.out

a.out:     file format elf64-x86-64


Disassembly of section .text:
(code omitted for brevity)
00000000004005ac :
  4005ac:       55                      push   %rbp
  4005ad:       48 89 e5                mov    %rsp,%rbp
  4005b0:       bf 6c 06 40 00          mov    $0x40066c,%edi
  4005b5:       e8 d6 fe ff ff          callq  400490 
  4005ba:       5d                      pop    %rbp
  4005bb:       c3                      retq   
  4005bc:       0f 1f 40 00             nopl   0x0(%rax)

请参阅?机器代码。 objdump实用程序以十六进制格式帮助打印,右侧显示相应的反汇编代码,左侧显示地址。