質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

リンカ

リンカはコンパイルされたオブジェクトコードに、必要なライブラリなどを付け加えて、実行可能ファイルを生成するプログラムです。コンパイルされたオブジェクトのコードを複数のファイルで取得し、"linked"という一つの実行可能のファイルを生成します。

Q&A

解決済

1回答

3607閲覧

Segmentation fault (core dumped)の具体的原因を知りたいです

退会済みユーザー

退会済みユーザー

総合スコア0

アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

リンカ

リンカはコンパイルされたオブジェクトコードに、必要なライブラリなどを付け加えて、実行可能ファイルを生成するプログラムです。コンパイルされたオブジェクトのコードを複数のファイルで取得し、"linked"という一つの実行可能のファイルを生成します。

0グッド

0クリップ

投稿2020/08/28 20:51

解決したいこととしましては、Segmentation fault (core dumped)が出ている原因を知りたいです。

test.asm

section .bss section .data MSG: db "Hello World!!", 10 MSG_LEN equ $-MSG section .text global main main: nop .spike: mov eax, 0 add eax, 5 sub eax, 2 .print: mov eax, 4 mov ebx, 1 mov ecx, MSG mov edx, MSG_LEN int 80h; .final: mov eax, 0 ret

test.asmを

nasm -g -f elf64 -o test.o test.asm

でオブジェクトファイルにして

ld test.o exit.o -o test -O0 -g -static

で実行ファイルにしました。
※exit.oというのは_startから_libc_start_mainを経由せずに_mainに移動するようにしたものです。
まずgdb -q testでデバッガモードに入り、ブレークポイントをmainにおき、runで実行して、nextiで一つ一つ実行していきました。

以下がアセンブラになります。

0x4000b0 <main> nop 0x4000b1 <main.spike> mov $0x0,%eax 0x4000b6 <main.spike+5> add $0x5,%eax 0x4000b9 <main.spike+8> sub $0x2,%eax 0x4000bc <main.print> mov $0x4,%eax 0x4000c1 <main.print+5> mov $0x1,%ebx 0x4000c6 <main.print+10> mov $0x6000e8,%ecx 0x4000cb <main.print+15> mov $0xe,%edx 0x4000d0 <main.print+20> int $0x80 ここでエラー Program received signal SIGSEGVSegmentation fault. 0x4000d2 <main.final> mov $0x0,%eax 0x4000d7 <main.final+5> retq 0x4000d8 <_start> callq 0x4000b0 <main>

実行していくと、下から5行目の

0x4000d0 <main.print+20> int $0x80

というところに来るとSegmentation fault (core dumped)になります。
調べてみると、
メモリが割り当てられていない領域にアクセスしようとした
書き込みが禁止されている領域に書き込もうとした
実行が禁止されている領域のコードを実行しようとした
等が原因なのですが、なぜそうなっているかが分かりません。

この時のレジスターの状況が以下になります。

rax 0x4 4 rbx 0x1 1 rcx 0x6000e8 6291688 rdx 0xe 14 rsi 0x0 0 rdi 0x0 0 rbp 0x0 0x0 rsp 0x7ffffffee028 0x7ffffffee028 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x0 0 r13 0x0 0 r14 0x0 0 r15 0x0 0 rip 0x4000d0 0x4000d0 <main.print+20> eflags 0x10306 [ PF TF IF RF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0

また添付画像のように0x4000d0 <main.print+20>にいるときにinfo registerとしたので、
0x4000d0 <main.print+20>が実行される前のレジスタの状況と考えて間違いはないですよね?
イメージ説明
調べに調べましたが原因が解決できないので質問しました。
宜しくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

まずはint 80h が何をする命令なのか調べてみてはどうでしょう。
そして、どういう目的でその命令を書いたのか考えましょう

投稿2020/08/28 21:25

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2020/08/29 09:19

相手に情報を与えてはいけない、をモットーにしておりますw
退会済みユーザー

退会済みユーザー

2020/08/31 21:47 編集

返信遅くなり申し訳ありません。 ご回答ありがとうございます。 システムコールについても調べていましたが、x86とx64で引っ張ってくる番号が違うらしく、ausyscallで再度調べてみると、writeに該当するシステムコールについては、raxにセットする値が4ではなく1だったことが判明しました。 また、x86とx64とでレジスタの値を格納していく順番が異なるらしく、そこも書き直しました。 なので再度アセンブラを書き直して、別の方法で試してみると無事表示されました。 Segmentation fault (core dumped)についてはまだ表示されていますが、とりあえず文字列のHello Worldが表示されたので解決とさせてください。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問