Использование GCC для создания читаемой сборки?
Мне было интересно, как использовать GCC в моем исходном файле C, чтобы сбрасывать мнемоническую версию машинного кода, чтобы я мог видеть, что мой код был скомпилирован. Вы можете сделать это с помощью Java, но мне не удалось найти способ с GCC.
Я пытаюсь перезаписать метод C в сборке и посмотреть, как GCC это будет большой помощью.
Ответы
Ответ 1
Если вы компилируете символы отладки, вы можете использовать objdump
для создания более читаемой разборки.
>objdump --help
[...]
-S, --source Intermix source code with disassembly
-l, --line-numbers Include line numbers and filenames in output
objdump -drwC -Mintel
хорош:
-
-r
показывает имена символов на переездах (так что вы хотите видеть puts
в call
инструкции ниже) -
-r
показывает динамические связи/имена символов (полезно для разделяемых библиотек) -
-C
отображает имена символов C++ -
-w
является "широким" режимом: он не строит -w рэп -C ode bytes -
-Mintel
: используйте GAS/binutils MASM-like .intel_syntax noprefix
синтаксис .intel_syntax noprefix
вместо AT & T -
-S
: чередовать строки источника с разборкой.
Вы можете поставить что-то вроде alias disas="objdump -drwCS -Mintel"
в ~/.bashrc
Пример:
> gcc -g -c test.c
> objdump -d -M intel -S test.o
test.o: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
#include <stdio.h>
int main(void)
{
0: 55 push ebp
1: 89 e5 mov ebp,esp
3: 83 e4 f0 and esp,0xfffffff0
6: 83 ec 10 sub esp,0x10
puts("test");
9: c7 04 24 00 00 00 00 mov DWORD PTR [esp],0x0
10: e8 fc ff ff ff call 11 <main+0x11>
return 0;
15: b8 00 00 00 00 mov eax,0x0
}
1a: c9 leave
1b: c3 ret
Ответ 2
Я хотел бы добавить к этим ответам, что если вы дадите gcc флаг -fverbose-asm
, ассемблер, который он испускает, будет намного понятнее читать.
Ответ 3
Используйте ключ -S (note: capital S) для GCC, и он выдает код сборки в файл с расширением .s. Например, следующая команда:
gcc -O2 -S foo.c
оставит сгенерированный код сборки в файле foo.s.
Сброс прямо из http://www.delorie.com/djgpp/v2faq/faq8_20.html (но удаление ошибочного -c
)
Ответ 4
Использование переключателя -S
для GCC на системах на базе x86 дает по умолчанию дамп синтаксиса AT & T, который может быть указан с помощью -masm=att
, например:
gcc -S -masm=att code.c
Если вы хотите создать дамп в синтаксисе Intel, вы можете использовать переключатель -masm=intel
, например:
gcc -S -masm=intel code.c
(Оба производят дампы code.c
в их различный синтаксис, в файл code.s
соответственно)
Для создания подобных эффектов с помощью objdump, вы хотите использовать --disassembler-options=
intel
/att
, пример (с --disassembler-options=
кода для иллюстрации различий в синтаксисе):
$ objdump -d --disassembler-options=att code.c
080483c4 <main>:
80483c4: 8d 4c 24 04 lea 0x4(%esp),%ecx
80483c8: 83 e4 f0 and $0xfffffff0,%esp
80483cb: ff 71 fc pushl -0x4(%ecx)
80483ce: 55 push %ebp
80483cf: 89 e5 mov %esp,%ebp
80483d1: 51 push %ecx
80483d2: 83 ec 04 sub $0x4,%esp
80483d5: c7 04 24 b0 84 04 08 movl $0x80484b0,(%esp)
80483dc: e8 13 ff ff ff call 80482f4 <[email protected]>
80483e1: b8 00 00 00 00 mov $0x0,%eax
80483e6: 83 c4 04 add $0x4,%esp
80483e9: 59 pop %ecx
80483ea: 5d pop %ebp
80483eb: 8d 61 fc lea -0x4(%ecx),%esp
80483ee: c3 ret
80483ef: 90 nop
а также
$ objdump -d --disassembler-options=intel code.c
080483c4 <main>:
80483c4: 8d 4c 24 04 lea ecx,[esp+0x4]
80483c8: 83 e4 f0 and esp,0xfffffff0
80483cb: ff 71 fc push DWORD PTR [ecx-0x4]
80483ce: 55 push ebp
80483cf: 89 e5 mov ebp,esp
80483d1: 51 push ecx
80483d2: 83 ec 04 sub esp,0x4
80483d5: c7 04 24 b0 84 04 08 mov DWORD PTR [esp],0x80484b0
80483dc: e8 13 ff ff ff call 80482f4 <[email protected]>
80483e1: b8 00 00 00 00 mov eax,0x0
80483e6: 83 c4 04 add esp,0x4
80483e9: 59 pop ecx
80483ea: 5d pop ebp
80483eb: 8d 61 fc lea esp,[ecx-0x4]
80483ee: c3 ret
80483ef: 90 nop
Ответ 5
godbolt - очень полезный инструмент, в списке есть только компиляторы С++, но вы можете использовать флаг -x c
для его получения обработайте код как C. Затем он сгенерирует список сборок для вашего кода бок о бок, и вы можете использовать параметр Colourise
для создания цветных полосок, чтобы визуально указать, какой исходный код сопоставляется сгенерированной сборкой. Например, следующий код:
#include <stdio.h>
void func()
{
printf( "hello world\n" ) ;
}
используя следующую командную строку:
-x c -std=c99 -O3
и Colourise
генерируют следующее:
![enter image description here]()
Ответ 6
Вы пробовали gcc -S -fverbose-asm -O source.c
затем source.s
сгенерированный source.s
ассемблера source.s
?
Сгенерированный ассемблерный код переходит в source.s
(вы можете переопределить его с помощью -O
имя ассемблера); -fverbose-asm
просит компилятор -fverbose-asm
некоторые комментарии ассемблера, "объясняя" сгенерированный код ассемблера. Опция -O
просит компилятор немного оптимизировать (он может оптимизировать больше с -O2
или -O3
).
Если вы хотите понять, что делает gcc
, попробуйте передать -fdump-tree-all
но будьте осторожны: вы получите сотни файлов дампа.
Кстати, GCC можно расширять с помощью плагинов или с помощью MELT (высокоуровневый домен-специфический язык для расширения GCC; от которого я отказался в 2017 году)
Ответ 7
Вы можете использовать gdb для этого, как objdump.
Эта выдержка взята из http://sources.redhat.com/gdb/current/onlinedocs/gdb_9.html#SEC64
Ниже приведен пример сборки смешанного источника + для Intel x86:
(gdb) disas /m main
Dump of assembler code for function main:
5 {
0x08048330 : push %ebp
0x08048331 : mov %esp,%ebp
0x08048333 : sub $0x8,%esp
0x08048336 : and $0xfffffff0,%esp
0x08048339 : sub $0x10,%esp
6 printf ("Hello.\n");
0x0804833c : movl $0x8048440,(%esp)
0x08048343 : call 0x8048284
7 return 0;
8 }
0x08048348 : mov $0x0,%eax
0x0804834d : leave
0x0804834e : ret
End of assembler dump.
Ответ 8
Используйте ключ -S (note: capital S) для GCC, и он выдает код сборки в файл с расширением .s. Например, следующая команда:
gcc -O2 -S -c foo.c
Ответ 9
Я не дал выстрел в gcc, но в случае g++. Следующая приведенная ниже команда работает для меня. -g для сборки отладки и -Wa, -adhln передается ассемблеру для распечатки с исходным кодом
g++ -g -Wa, -adhln src.cpp