web-dev-qa-db-ja.com

Linuxでcソースコードからnasmコンパイル可能なアセンブリコードを生成するにはどうすればよいですか?

テストプラットフォームは32ビットLinuxです。

基本的に、gccを使用してIntelスタイルとAt&Tスタイルの両方のアセンブリコードを生成できることは知っていますが、できない nasm/tasmを直接使用して、生成されたIntelスタイルのアセンブリコードgccをコンパイルします。

私はWindowsとLinuxプラットフォームの両方でプロジェクト分析asmコードを実行しているので、nasm\yasmのようなプラットフォームに依存しないアセンブラーで両方をコンパイルできれば、はるかに簡単な時間を過ごすことができると思います...

だから私の質問は、Linux上のcソースコードからnasmコンパイル可能なアセンブリコードを生成する方法ですか?

22
lllllllllllll

オブジェクトファイルを逆アセンブルする方が、gccで生成されたアセンブリコードを使用するよりも良い方法だと思います。

  1. まず、ソースコードからオブジェクトファイルを生成します。

    gcc -fno-asynchronous-unwind-tables -O2 -s -c -o main.o main.c
    

    -fno-asynchronous-unwind-tables.eh_frameのような不要なセクションを生成しません

    -O2は、asmがひどくないように最適化します。オプションで、-Os(速度よりもサイズ)または-O3(自動ベクトル化を含む完全な最適化)を使用します。また、CPUを調整し、CPUがサポートする拡張機能を-march=nativeまたは-march=haswellまたは-march=znver1(Zen)で使用することもできます。

    -s:実行可能ファイルを小さくする(ストリップ)

    -c -o main.o:コンパイルしますがリンクしません。main.oというオブジェクトファイルを生成します

  2. objconv を使用してnasmコードを生成します。

    objconv -fnasm main.o
    

    結果はmain.asmに保存されます。

  3. 結果はNasm構文に非常に近くなります。ただし、警告/エラーを排除するために、いくつかの小さな調整が必要になる場合があります。 Nasmでコンパイルしてみてください

    nasm -f elf32 main.asm
    

    エラー/警告を手動で修正します。例えば:

    • align=N行から.SECTIONおよびexecute/noexecuteワードを削除します。
    • global宣言からテキスト: functionを削除します
    • default rel行を削除します
    • 必要に応じて、空のセクションを削除します
  4. Gccを使用して、ステップ3でNasmによって生成された結果のmain.oをリンクします。

    gcc main.o
    

    Ldを使用してリンクすることもできますが、はるかに困難です。

35

怠け者の場合: https://github.com/diogovk/c2nasm

そこには、バブケンバーダニアンの提案を自動的に実行するスクリプトがあります。

9
diogovk

objconvなしでそれを行う方法がここにあります

ndisasm -u <(objdump -j .text -d main.o | cut -d: -f2 | cut -d$'\t' -f 2 | Perl -ne 'next if /file/; s/\s+//g; print' | xxd -r -p)
0
skyfire