467

どうやってこれを行うのですか?

何かがどのようにコンパイルされているかを分析したい場合、出力されたアセンブリ コードをどのように取得しますか?

4

17 に答える 17

521

-Sgcc(またはg ++)のオプションを使用します。

gcc -S helloworld.c

これにより、helloworld.c上でプリプロセッサ(cpp)が実行され、最初のコンパイルが実行されてから、アセンブラが実行される前に停止します。

デフォルトでは、これはファイルを出力しますhelloworld.s。オプションを使用して、出力ファイルを設定することもでき-oます。

gcc -S -o my_asm_output.s helloworld.c

もちろん、これは元のソースがある場合にのみ機能します。結果のオブジェクトファイルしかない場合の代替手段はobjdump、オプションを設定して--disassemble(または-d省略形の場合)、を使用することです。

objdump -S --disassemble helloworld > helloworld.dump

-gこのオプションは、オブジェクトファイルに対して(コンパイル時に)デバッグオプションが有効になっていて、ファイルが削除されていない場合に最適に機能します。

実行file helloworldすると、objdumpを使用して取得できる詳細レベルがわかります。

于 2008-09-26T00:19:43.220 に答える
195

これにより、C コードと行番号が織り交ぜられたアセンブリ コードが生成され、どの行がどのコードを生成するかをより簡単に確認できます。

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

プログラマー向けのアルゴリズム の3 ページ (PDF の全体の 15 ページ目) にあります。

于 2008-09-26T02:51:05.243 に答える
52

次のコマンド ラインは、Christian Garbin のブログからのものです。

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

暗黙のキャストを含むルーチンに対して、Win-XP の DOS ウィンドウから G++ を実行しました。

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'

出力は、元の C++ コードが散在するアセンブルされた生成コードです (C++ コードは、生成された 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)
于 2013-09-29T22:07:28.830 に答える
33

-S スイッチを使用する

g++ -S main.cpp

またはgccでも

gcc -S main.c

こちらもご覧ください

于 2008-09-26T00:11:06.203 に答える
14

表示したいものが出力のリンクに依存している場合は、前述のgcc -Sに加えて、出力オブジェクトファイル/実行可能ファイルのobjdumpも役立つ場合があります。これは、デフォルトのobjdump構文をより読みやすいnasm構文に変換するLorenMerrittによる非常に便利なスクリプトです。

#!/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;

これはgcc-Sの出力にも使用できると思います。

于 2008-09-26T00:14:23.607 に答える
11

さて、皆さんが言うように、-S オプションを使用してください。-save -temps オプションを使用すると、前処理済みファイル ( .i)、アセンブリ ファイル ( .s)、およびオブジェクト ファイル (*.o) も取得できます。(-E、-S、および -c を使用してそれぞれを取得します。)

于 2013-06-13T08:56:37.457 に答える
9

LLVM アセンブリを探している場合:

llvm-gcc -emit-llvm -S hello.c
于 2011-10-24T06:18:37.720 に答える
9

誰もが指摘したように、-SGCC のオプションを使用します。また、最適化オプションを追加するかどうかによって、結果が (大幅に!) 異なる可能性があることも付け加えておきます (-O0なしの場合、積極的な-O2最適化の場合)。

特に RISC アーキテクチャーでは、コンパイラーは、最適化を行う際に認識できないほどコードを変換することがよくあります。結果を見るのは印象的で魅力的です!

于 2008-09-26T02:06:06.910 に答える
9

前述のように、-S フラグを見てください。

また、'-fdump-tree' ファミリのフラグ、特に '-fdump-tree-all' を調べることも価値があります。これにより、gcc の中間形式の一部を確認できます。これらは多くの場合、(少なくとも私にとっては) アセンブラーよりも読みやすく、最適化パスがどのように実行されるかを確認できます。

于 2008-10-11T16:31:10.057 に答える
8

-Sオプションを使用します。

gcc -S program.c
于 2008-09-26T00:11:32.117 に答える
6

から: http://www.delorie.com/djgpp/v2faq/faq8_20.html

gcc -c -g -Wa,-a,-ad [その他の GCC オプション] foo.c > foo.lst

PhirePhlyの答えの代わりに または、誰もが言ったように -S を使用してください。

于 2011-01-04T12:02:58.243 に答える
2

オプションとして「-S」を使用します。ターミナルにアセンブリ出力が表示されます。

于 2010-12-16T02:18:14.433 に答える