Jak uzyskać wyjście asemblera ze źródła C / C++ w gcc?

Jak to się robi?

Jeśli chcę przeanalizować, jak coś jest kompilowane, jak Mogę uzyskać kod wysyłanego assembly?

Author: Ryan Tenney, 2008-09-26

14 answers

Użyj opcji -S do gcc (lub g++).

gcc -S helloworld.c

Spowoduje to uruchomienie preprocesora (cpp) nad helloworld.c, wykonaj początkową kompilację, a następnie zatrzymaj się przed uruchomieniem asemblera.

Domyślnie wyświetli plik helloworld.s. Plik wyjściowy można nadal ustawić za pomocą opcji -o.

gcc -S -o my_asm_output.s helloworld.c

Oczywiście działa to tylko wtedy, gdy masz oryginalne źródło. Alternatywą, jeśli masz tylko wynikowy plik obiektowy, jest użycie objdump, ustawiając opcję --disassemble (lub -d dla formy skróconej).

objdump -S --disassemble helloworld > helloworld.dump

Ta opcja działa najlepiej, jeśli opcja debugowania jest włączona dla pliku obiektowego (-g w czasie kompilacji) i plik nie został rozebrany.

Uruchomienie file helloworld da ci pewne wskazówki co do poziomu szczegółowości, który uzyskasz używając objdump.

 346
Author: Andrew Edgecombe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 01:33:38

Spowoduje to wygenerowanie asm z kodem C + numerami linii przeplecionych, aby łatwiej zobaczyć, które linie generują jaki kod.

# create assembler code:
c++ -S -fverbose-asm -g -O2 test.cc -o test.s
# create asm interlaced with source lines:
as -alhnd test.s > test.lst

Znalezione w algorytmy dla programistów, Strona 4.

 154
Author: PhirePhly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 02:51:05

Poniższy wiersz poleceń pochodzi z Blog Christiana Garbina

g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt

Uruchomiłem G++ z okna DOS na Win-XP, przeciwko rutynie, która zawiera ukrytą obsadę

c:\gpp_code>g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt
horton_ex2_05.cpp: In function `int main()':
horton_ex2_05.cpp:92: warning: assignment to `int' from `double'

Wyjście jest sklejone wygenerowanym kodem iterspersed z oryginalnym kodem C++ (kod C++ jest wyświetlany jako komentarze w wygenerowanym strumieniu asm)

  16:horton_ex2_05.cpp **** using std::setw;
  17:horton_ex2_05.cpp ****
  18:horton_ex2_05.cpp **** void disp_Time_Line (void);
  19:horton_ex2_05.cpp ****
  20:horton_ex2_05.cpp **** int main(void)
  21:horton_ex2_05.cpp **** {
 164                    %ebp
 165                            subl $128,%esp
?GAS LISTING C:\DOCUME~1\CRAIGM~1\LOCALS~1\Temp\ccx52rCc.s
166 0128 55                    call ___main
167 0129 89E5          .stabn 68,0,21,LM2-_main
168 012b 81EC8000      LM2:
168      0000
169 0131 E8000000      LBB2:
169      00
170                    .stabn 68,0,25,LM3-_main
171                    LM3:
172                            movl $0,-16(%ebp)
 42
Author: Cr McDonough,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 01:08:07

Użyj przełącznika-S

g++ -S main.cpp

Lub również z gcc

gcc -S main.c

Zobacz też to

 21
Author: Doug T.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 00:11:06

Jeśli to, co chcesz zobaczyć, zależy od linkowania wyjścia, wtedy objdump na pliku obiektu wyjściowego/pliku wykonywalnym może być również użyteczny oprócz wspomnianego gcc - S. oto bardzo przydatny skrypt Loren Merritt, który konwertuje domyślną składnię objdump na bardziej czytelną składnię nasm:

#!/usr/bin/perl -w
$ptr='(BYTE|WORD|DWORD|QWORD|XMMWORD) PTR ';
$reg='(?:[er]?(?:[abcd]x|[sd]i|[sb]p)|[abcd][hl]|r1?[0-589][dwb]?|mm[0-7]|xmm1?[0-9])';
open FH, '-|', '/usr/bin/objdump', '-w', '-M', 'intel', @ARGV or die;
$prev = "";
while(<FH>){
    if(/$ptr/o) {
        s/$ptr(\[[^\[\]]+\],$reg)/$2/o or
        s/($reg,)$ptr(\[[^\[\]]+\])/$1$3/o or
        s/$ptr/lc $1/oe;
    }
    if($prev =~ /\t(repz )?ret / and
       $_ =~ /\tnop |\txchg *ax,ax$/) {
       # drop this line
    } else {
       print $prev;
       $prev = $_;
    }
}
print $prev;
close FH;

Podejrzewam, że może to być również użyte na wyjściu gcc-S.

 12
Author: Dark Shikari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 00:14:23

Jak wszyscy zauważyli, użyj opcji -S do GCC. Chciałbym również dodać, że wyniki mogą się różnić (szalenie!) w zależności od tego, czy dodasz opcje optymalizacji ({[1] } dla none, -O2 dla agresywnej optymalizacji).

W szczególności na architekturach RISC, kompilator często przekształca kod prawie nie do poznania, wykonując optymalizację. To imponujące i fascynujące patrzeć na wyniki!

 7
Author: Dan Lenski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 02:06:06

Cóż, jak wszyscy mówili, użyj opcji-S. Jeśli użyjesz opcji-save-temps, możesz również uzyskać wstępnie przetworzony plik (.i), plik assembly (.s) I plik obiektowy (*.o). (uzyskaj każdy z nich za pomocą -E, - S I-c.)

 7
Author: METADATA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-13 08:56:37

Użyj opcji-S:

gcc -S program.c
 6
Author: Jeremy Ruten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 00:11:32

Jak wspomniano wcześniej, spójrz na flagę-s.

Warto również przyjrzeć się rodzinie FLAG'-fdump-tree', w szczególności '- fdump-tree-all', która pozwala zobaczyć niektóre z form pośrednich gcc. Często mogą być bardziej czytelne niż asembler( przynajmniej dla mnie) i pozwalają zobaczyć, jak przebiegają przejścia optymalizacyjne.

 6
Author: Chris Jefferson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-11 16:31:10

Jeśli szukasz montażu LLVM:

llvm-gcc -emit-llvm -S hello.c
 6
Author: mcandre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-24 06:18:37

From: http://www.delorie.com/djgpp/v2faq/faq8_20.html

Gcc-c-g-Wa,-a, - ad [inne opcje GCC] foo.c > foo.lst

W alternatywie dla odpowiedzi PhirePhly ' ego Albo po prostu użyj-S, jak wszyscy mówili.

 4
Author: Anonymous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-04 12:02:58

Nie widzę takiej możliwości wśród odpowiedzi, prawdopodobnie dlatego, że pytanie pochodzi z 2008 roku, ale w 2018 roku możesz użyć strony internetowej Matta Goldbolta https://godbolt.org

Możesz także lokalnie git clone i uruchomić jego projekt https://github.com/mattgodbolt/compiler-explorer

 4
Author: 421,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-24 15:27:12

Wyjście tych komunikatów

Oto kroki, aby zobaczyć / wydrukować kod złożenia dowolnego programu C w systemie Windows

Konsola /terminal/ wiersz polecenia:

  1. Napisz program C w edytorze kodu C, takim jak codeblocks i zapisz go z rozszerzeniem .c

  2. Skompilować i uruchomić.

  3. Po pomyślnym uruchomieniu przejdź do folderu, w którym zainstalowałeś kompilator gcc i podaj

    Wykonując polecenie, aby uzyskać ' .s "akta".c" plik

    C:\ gcc> gcc-s pełna ścieżka pliku C ENTER

    Przykładowe polecenie (jak w moim przypadku)

    C:\gcc> gcc-S D:\Aa_C_Certified\alternate_letters.c

    To wyjście a ' .s "plik oryginału".C ' file

4 . Następnie wpisz następujące polecenie

C; \ gcc> nazwa pliku cpp.s ENTER

Przykładowe polecenie (jak w moim przypadku)

C; \ gcc> cpp alternate_letters.s

To wydrukuje / wyświetli cały zestaw kod języka Twojego programu C.

 2
Author: Ashutosh K Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-25 03:17:38

Użyj opcji "- S". Wyświetla wyjście montażu w terminalu.

 1
Author: Pizearke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-16 02:18:14