Как получить полный вывод ассемблера в gcc? - PullRequest
6 голосов
/ 07 сентября 2010

Я знаю, что могу получить ассемблер исходный код, сгенерированный компилятором, используя:

gcc -S ...

, хотя это досадно не дает мне объектный файл как частьпроцесс.

Но как я могу получить все о скомпилированном коде?Я имею в виду адреса, сгенерированные байты и т. Д.

Инструкции, выводимые gcc -S, ничего не говорят мне о длине команд или кодировках, что я и хочу видеть.

Ответы [ 5 ]

10 голосов
/ 08 сентября 2010

Мне нравится objdump для этого, но наиболее полезные опции неочевидны - особенно если вы используете его в объектном файле, который содержит перемещения, а не конечный двоичный файл.

objdump -d some_binary делает разумную работу.

objdump -d some_object.o менее полезен, потому что вызовы внешних функций не разбираются услужливо:

...
00000005 <foo>:
   5:   55                      push   %ebp
   6:   89 e5                   mov    %esp,%ebp
   8:   53                      push   %ebx
...
  29:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  30:   e8 fc ff ff ff          call   31 <foo+0x2c>
  35:   89 d8                   mov    %ebx,%eax
...

call на самом деле printf()... добавление флага -r помогает в этом;это отмечает перемещения.objdump -dr some_object.o дает:

...
  29:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
                        2c: R_386_32    .rodata.str1.1
  30:   e8 fc ff ff ff          call   31 <foo+0x2c>
                        31: R_386_PC32  printf
...

Затем я считаю полезным видеть каждую строку с пометкой <symbol+offset>objdump есть удобная опция для этого, но он имеет раздражающий побочный эффект отключения дампа реальных байтов - objdump --prefix-addresses -dr some_object.o дает:

...
00000005 <foo> push   %ebp
00000006 <foo+0x1> mov    %esp,%ebp
00000008 <foo+0x3> push   %ebx
...

Но оказывается, что вы можете отменить этопредоставив еще один неясный вариант, наконец-то дойдя до моего любимого objdump заклинания:

objdump --prefix-addresses --show-raw-insn -dr file.o

, которое выдает следующий результат:

...
00000005 <foo> 55                       push   %ebp
00000006 <foo+0x1> 89 e5                        mov    %esp,%ebp
00000008 <foo+0x3> 53                           push   %ebx
...
00000029 <foo+0x24> c7 04 24 00 00 00 00        movl   $0x0,(%esp)
                        2c: R_386_32    .rodata.str1.1
00000030 <foo+0x2b> e8 fc ff ff ff              call   00000031 <foo+0x2c>
                        31: R_386_PC32  printf
00000035 <foo+0x30> 89 d8                       mov    %ebx,%eax
...

И если вы создали с помощью символов отладки (т. Е. Скомпилированы с -g) и вы заменили -dr на -Srl, он попытается аннотировать вывод соответствующими строками-источниками.

3 голосов
/ 08 сентября 2010

Самый простой способ получить быстрый список - использовать опцию -a для ассемблера, что можно сделать, поставив -Wa,-a в командной строке gcc.Вы можете использовать различные модификаторы для опции a, чтобы точно влиять на то, что выходит - см. Справочную страницу as (1).

1 голос
/ 07 сентября 2010

gcc создаст исходный файл на ассемблере. Затем вы можете использовать as -a yourfile.S для создания списка, который включает смещения и закодированные байты для каждой инструкции. -a также имеет несколько подопций для управления тем, что отображается в файле списка (as --help выдаст их список вместе с другими доступными опциями).

0 голосов
/ 08 сентября 2010
nasm -f elf xx.asm -l x.lst

gcc xx.c xx.o -o xx

генерирует файл «list» x.lst, который предназначен только для xx.asm

для xx.c, вместе с xx.asm вы можете скомпилировать их оба, а затем использовать «gdb» - gnuотладчик

0 голосов
/ 07 сентября 2010

Звучит так, будто вы хотите дизассемблер. objdump в значительной степени стандарт (otool в Mac OS X); в сочетании с любой информацией о файле карты, которую предоставляет вам компоновщик, разборка вашего объектного файла должна дать вам все, что вы хотите.

...