Почему a.out не на машинном языке?

Я компилирую следующую программу с 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]

person jaynp    schedule 27.12.2012    source источник
comment
xxd -b a.out. Там 0 и 1. :)   -  person netcoder    schedule 28.12.2012


Ответы (5)


Файл находится в 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  ......
person Adam Sznajder    schedule 27.12.2012
comment
Вы также должны упомянуть, что это касается каждого файла, а не только исполняемого файла. - person sepp2k; 28.12.2012
comment
Да, аналоговых файлов не существует, поэтому каждый отдельный файл состоит из двоичных цифр (битов). Машинный код, текстовые файлы, исходные файлы, объектные файлы, базы данных. Все бинарные файлы. - person Mats Petersson; 28.12.2012

Это какой-то формат исполняемого файла. В Linux это, вероятно, ELF, в Mac OS X это, вероятно, Mach-O и так далее. Существует даже формат a.out, но он уже не так распространен.

Это не могут быть просто машинные инструкции — операционной системе нужна информация о том, как ее загружать, какие динамические библиотеки к ней подключать и т. д.

person Carl Norum    schedule 27.12.2012
comment
Хотя это правда, я думаю, вы упустили основную путаницу ОП. Даже если бы это были голые машинные инструкции, ОП определенно не увидел бы 0 и 1, когда он открывает файл в текстовом редакторе (чего он, по-видимому, и ожидал). - person sepp2k; 28.12.2012

Символы также состоят из нулей и единиц, и компьютер не может отличить их друг от друга. Вы попросили его показать файл, и он это сделал.

В дополнение к машинным инструкциям двоичный файл также содержит макет и необязательную отладочную информацию, которые могут быть читаемыми строками.

person Mark Ransom    schedule 27.12.2012

Формат a.out понятен загрузчику используемой ОС. Те разные тексты, которые вы видите, являются маркерами для разных частей 0 и 1, которые вы ожидаете.

? и ` показывают места, где есть двоичные непечатаемые данные.

person Hogan    schedule 27.12.2012

В наши дни типичным форматом в системах 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 выводит его в шестнадцатеричном формате с соответствующим дизассемблированным кодом справа и адресами слева.

person Dietrich Epp    schedule 27.12.2012