セグメンテーション違反でクラッシュするアセンブリで記述されたプログラムがあります。(コードは関係ありませんが、ここにあります。)
私の質問は、GDBを使用してアセンブリ言語プログラムをデバッグする方法です。
GDBで実行してバックトレースを実行しようとすると、意味のある情報が得られません。(16進オフセットのみ。)
プログラムをデバッグするにはどうすればよいですか?
(ちなみに、私はUbuntuでNASMを使用していますが、それが何らかの形で役立つ場合は。)
セグメンテーション違反でクラッシュするアセンブリで記述されたプログラムがあります。(コードは関係ありませんが、ここにあります。)
私の質問は、GDBを使用してアセンブリ言語プログラムをデバッグする方法です。
GDBで実行してバックトレースを実行しようとすると、意味のある情報が得られません。(16進オフセットのみ。)
プログラムをデバッグするにはどうすればよいですか?
(ちなみに、私はUbuntuでNASMを使用していますが、それが何らかの形で役立つ場合は。)
私はそれを直接ロードしgdb
、命令ごとにステップスルーし、すべてのレジスタとメモリの内容を監視します。
私はあなたがそこで知らないことをあなたに話していないと確信していますが、プログラムはこの種のアプローチを正当化するのに十分単純なようです。より複雑なコードには、バックトラッキング(さらにはブレークポイント)のような凝ったデバッグのトリックを残しておきます。
特定の問題(以下に言い換えられたコード)に関して:
extern printf
SECTION .data
format: db "%d",0
SECTION .bss
v_0: resb 4
SECTION .text
global main
main:
push 5
pop eax
mov [v_0], eax
mov eax, v_0
push eax
call printf
スタックに5をプッシュし、その後にメモリ内のその5のアドレスをプッシュしているように見えます(v_0
)。を呼び出したい場合は、ある時点でフォーマット文字列のアドレスをプッシュする必要があると確信していますprintf
。不正なフォーマット文字列が与えられるのは親切ではありません。
おそらくあなたの:
mov eax, v_0
する必要があります:
mov eax, format
そして、その呼び出しの後に、重要ではないとして中断したコードがもっとあるとprintf
思います(そうしないと、戻ったときに決して着陸しないことになります)。
コードを(gccで)リンクするときに、Stabsマーカーを使用してアセンブルできるはずです。
YASMを使用し、オプションを使用して組み立てることをお勧めし-dstabs
ます。
$ yasm -felf64 -mamd64 -dstabs file.asm
これが私がアセンブリプログラムを組み立てる方法です。
NASMコードとYASMコードは、ほとんどの部分で交換可能です(YASMには、NASMでは使用できない拡張機能がいくつかありますが、すべてのNASMコードはYASMで適切にアセンブルされています)。
gccを使用して、アセンブルされたオブジェクトファイルをリンクするか、CまたはC++コードでコンパイルします。gccを使用-gstabs+
する場合、デバッグマーカーを使用してコンパイルするために使用します。