CのソースファイルでGCCを使用して、ニーモニックバージョンのマシンコードをダンプし、コードのコンパイル先を確認する方法を考えていました。あなたはJavaでこれを行うことができますが、私はGCCで方法を見つけることができませんでした。
私はアセンブリでCメソッドを書き直そうとしていますが、GCCがそれをどのように行うかを確認すると、大きな助けになります。
CのソースファイルでGCCを使用して、ニーモニックバージョンのマシンコードをダンプし、コードのコンパイル先を確認する方法を考えていました。あなたはJavaでこれを行うことができますが、私はGCCで方法を見つけることができませんでした。
私はアセンブリでCメソッドを書き直そうとしていますが、GCCがそれをどのように行うかを確認すると、大きな助けになります。
回答:
デバッグシンボルを使用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
「ワイド」モード:マシンコードのバイトを改行しない-Mintel
:.intel_syntax noprefix
AT&Tの代わりにGAS / binutils MASMのような構文を使用-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
-Wa,-adhln -g to gcc
。これは、アセンブラがガスであることを前提としており、常にそうであるとは限りません。
-Mintel
ます。
GCCにフラグを付ける-fverbose-asm
と、
生成されたアセンブリコードにコメント情報を追加して、読みやすくします。
[...]追加されたコメントは次のとおりです。
- コンパイラのバージョンとコマンドラインオプションに関する情報
- FILENAME:LINENUMBER:CONTENT OF LINEの形式の、アセンブリ命令に関連付けられたソースコード行
- 高レベルの式がさまざまなアセンブリ命令のオペランドに対応するヒント。
objdump
- objdump -drwCS -Mintel
に使用されていたすべてのスイッチが失われるので、どうすればverbose
with などを使用できobjdump
ますか?それで-fverbose-asm
、gccのように、asmコードでコメントを付けることができますか?
-fverbose-asm
、出力のASM構文のコメントの形ではなく、中に何も余分を置くディレクティブにされる追加.o
ファイル。組み立て時にすべて破棄されます。逆アセンブリの代わりにコンパイラのasm出力を確認します。たとえば、godbolt.orgで、マウスオーバーを介してソース行と簡単に一致させ、対応するソース/ asm行の色を強調表示できます。 GCC / clangアセンブリの出力から「ノイズ」を取り除く方法は?
-S(注:大文字のS)スイッチをGCCに使用すると、アセンブリコードが拡張子.sのファイルに出力されます。たとえば、次のコマンド:
gcc -O2 -S foo.c
生成されたアセンブリコードをファイルfoo.sに残します。
http://www.delorie.com/djgpp/v2faq/faq8_20.htmlから直接取り込んだ(ただし、誤ったものを削除した-c
)
gcc -march=native -O3 -save-temps
。を使用-c
して、リンクなどを試みなくても、オブジェクトファイルの作成を停止できます。
-save-temps
興味深いのは、コードが生成したコードを1つに-S
まとめてダンプするので興味深いです。しかし -save-temps
、現在のディレクトリにすべてをダンプしますが、これは面倒です。コードを検査するツールというよりは、GCCのデバッグオプションとして意図されているようです。
-S
x86ベースのシステムでGCCへのスイッチを使用すると、デフォルトで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
スイッチの例を使用します(構文の違いを示すコードダンプを使用)。
$ 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 <puts@plt>
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 <puts@plt>
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
gcc -S -masm=intel test.c
私にとって正確に機能しなかったので、次のようなIntelとAT&Tの構文の雑種を手に入れました:のmov %rax, QWORD PTR -24[%rbp]
代わりに:movq -24(%rbp), %rax
。
.o
、ASMファイルの並列出力を実行するときにも機能することに注意してください。つまり、-Wa,-ahls -o yourfile.o yourfile.cpp>yourfile.asm
-M
オプションを使用できますが、それは同じですが--disassembler-options
、はるかに短いです。たとえばobjdump -d -M intel a.out | less -N
godboltは非常に便利なツールです。リストにはC ++コンパイラしかありませんが、-x c
フラグを使用してコードをCとして扱うことができます。コードのアセンブリリストが並べColourise
て生成され、オプションを使用して生成できます。生成されたアセンブリにマップするソースコードを視覚的に示す色付きのバー。たとえば、次のコード:
#include <stdio.h>
void func()
{
printf( "hello world\n" ) ;
}
次のコマンドラインを使用します。
-x c -std=c99 -O3
そしてColourise
以下を生成します:
-masm=intel
が、残りはどうですか?
-x c
あなたは試すでしgcc -S -fverbose-asm -O source.c
生成に見て、その後source.s
アセンブラファイル?
生成されたアセンブラコードが入りsource.s
ます(-o
アセンブラファイル名でオーバーライドできます)。この-fverbose-asm
オプションは、生成されたアセンブラコードを「説明する」アセンブラコメントを発行するようにコンパイラに要求します。この-O
オプションは、コンパイラーにビットを最適化するように要求します(-O2
またはでさらに最適化できます-O3
)。
何gcc
が行われているのかを理解したい場合は、渡してみてください。-fdump-tree-all
ただし、注意が必要です。何百ものダンプファイルが取得されます。
ところで、GCCはプラグインまたはMELT(GCCを拡張するための高レベルのドメイン固有の言語です。私は2017年に放棄しました)を介して拡張可能です。
source.s
多くの人がコンソールでのプリントアウトを期待するので、出力はになるだろうと多分言及します。
-S -o-
stdoutにダンプします。 -masm=intel
NASM / YASM構文を使用する場合に役立ちます。(しかし、それqword ptr [mem]
だけではなくを使用しているqword
ため、NASM / YASMよりもIntel / MASMに似ています)。 gcc.godbolt.orgはダンプを整理するという素晴らしい仕事をします:オプションでコメントのみの行、未使用のラベル、アセンブラディレクティブを削除します。
-Og
は、さらに優れてい-O1
ます。これは、「デバッグ用に最適化する」ことを意味し、ソースが言うことをすべて行う、トリッキーでわかりにくい最適化をあまり行わずにasmを作成します。それはgcc4.8から利用可能ですが、clang 3.7にはまだありません。IDKは、それに対して何を反対するか決定しました。
これには、objdumpのようにgdbを使用できます。
この抜粋は、http://sources.redhat.com/gdb/current/onlinedocs/gdb_9.html#SEC64から取得されます
以下は、Intel x86のソース+アセンブリの混合を示す例です。
(gdb)disas / m main 関数mainのアセンブラコードのダンプ: 5 { 0x08048330:%ebpをプッシュ 0x08048331:mov%esp、%ebp 0x08048333:サブ$ 0x8、%esp 0x08048336:および$ 0xfffffff0、%esp 0x08048339:サブ$ 0x10、%esp 6 printf( "Hello。\ n"); 0x0804833c:movl $ 0x8048440、(%esp) 0x08048343:0x8048284を呼び出します 7は0を返します。 8} 0x08048348:mov $ 0x0、%eax 0x0804834d:残す 0x0804834e:ret アセンブラーダンプの終わり。
set disassembly-flavor intel
コマンドを使用します。
私はgccにショットを与えていませんが、g ++の場合です。以下のコマンドは私にとってはうまくいきます。-gはデバッグビルド用で、-Wa、-adhlnはソースコードをリストするためにアセンブラに渡されます。
g ++ -g -Wa、-adhln src.cpp
stdoutへのリスト出力を生成するには、gccまたはg ++のオプションとして-Wa、-adhlnを使用します。
-Wa、...は、アセンブラパーツのコマンドラインオプション用です(C / ++コンパイル後にgcc / g ++で実行)。これは、呼び出しとして内部的に(Windowsの場合as.exe)。見る
> --helpとして
コマンドラインとして、gcc内のアセンブラツールの詳細ヘルプを表示します