2016-09-23 4 views
1

Linuxでnasmを使用してアセンブリ言語プログラムを作成しています。gdbを使用してデバッグ中のメッセージ:関数_startから終了するまで単一のステップ実行

(gdb) break 2 
Note: breakpoints 1 and 2 also set at pc 0x4000b0. 
Breakpoint 3 at 0x4000b0: file new3.asm, line 2. 

(gdb) break 3 
Note: breakpoints 1, 2 and 3 also set at pc 0x4000b0. 
Breakpoint 4 at 0x4000b0: file new3.asm, line 3. 
:問題は、それはまた、「関数_startから出るまで、シングルステップ」

を_start関数内のステップとメッセージを与えていない、GDB、私はライン1の後にブレークポイントを設定すると、それは言うを使用してデバッグ中です

私はコマンドを使用して、それを組み立てるとリンクしています:

nasm -g -f elf64 new3.asm 
ld -g new3.o 

その後、私はそれがgdb new3.outを使用してデバッグします。 gdbのバージョンは7.11.1

プログラムは以下です:

section .text 
    global _start ;must be declared for linker (ld) 
_start:    ;tells linker entry point 
    call sum 
    mov edx,len  ;message length 
    mov ecx,msg  ;message to write 
    mov ebx,1  ;file descriptor (stdout) 
    mov eax,4  ;system call number (sys_write) 
    int 0x80  ;call kernel 
    mov eax,1  ;system call number (sys_exit) 
    int 0x80  ;call kernel 

sum: 
    mov  eax, ecx 
    add  eax, edx 
    add  eax, '0' 
    ret 
section .data 
msg db 'Hello, world!', 0xa ;string to be printed 
len equ $ - msg  ;length of the string 

iは、デバッグのための_start内でステップ実行することができますどのように、これの意味は何ですか?

(gdb) break 3 
Note: breakpoints 1, 2 and 3 also set at pc 0x4000b0. 
Breakpoint 4 at 0x4000b0: file new3.asm, line 3. 
+0

64ビットコードから 'int 0x80' 32ビットシステムコールABIを使用しないでください。代わりに 'syscall'を使用してください。それは、異なる呼び出し番号、および異なるレジスタ使用法を有する。 –

答えて

1

使用nasm -f elf64 -F dwarf -g new3.asmドワーフデバッグ情報、デフォルトではない(スタブ)を作成します。 (デフォルト値はnasm -felf64 -yです)。 yasm -felf64 -gdwarf2 new3.asmの作品もあります。 (実際にはyasmのために-gdwarf2を残しても、シングルステッピングが機能します:デフォルトでは十分です。)

gdbは、指示(stepi)ではなく、ソース行でシングルステップすることができます。 ld -gは必要ありません。何もしません。

おそらくldの代わりにgcc -nostdlib -g new3.oとリンクしてください。 ldコマンドラインにダイナミックライブラリを追加した場合、ldのデフォルトのELFインタプリタパスは現代のx86-64マルチシステムでは役に立たないため、バイナリが壊れてしまいます。 Building an executable from asm source that defines _start vs. main, static or dynamicを参照してください。

また、32ビットABIの64ビットコードint 0x80も使用しないでください。


使用stepi(又はsi)命令によって代わりのソース線によって進みます。

b *0x4000b0を使用すると、数値アドレスに基づいてブレークポイントを設定できます。また、エントリポイントにブレークポイントを設定するには、b _startのようなラベル名を使用します。

gdbでasmをデバッグするためのヒントについては、タグwikiの最後を参照してください。


ファイル内の最初の命令は、4行目にあるので、b 1b 4両方がCALL命令にブレークポイントを設定ことは驚くべきことではありません。

b 5 CALLの後の命令にブレークポイントを設定しません。この部分は、gdbがSTABSデバッグ情報(DWARFまたはDWARF2ではなく)しか持っていない場合でも動作しますが、シングルステップは実行されません。なぜIDK。

(gdb) b _start 
Breakpoint 1 at 0x4000b0 
(gdb) b 5 
Breakpoint 2 at 0x4000b5: file new3.asm, line 5. 
(gdb) r 
Starting program: /home/peter/src/SO/a.out 

Breakpoint 1, 0x00000000004000b0 in _start() 
関連する問題