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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

アセンブリ言語

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

WSL(Windows Subsystem for Linux)

WSL (Windows Subsystem for Linux) は、Windows10のOS上でLinux向けのバイナリプログラムを実行可能にする機能です。また、WindowsOSのAPIを用いた仕組みを提供しており、Linux側からWindowsOSへのファイルアクセスもできます。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

2回答

4104閲覧

アセンブリが Segmentation Fault になる

tails

総合スコア22

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

アセンブリ言語

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

WSL(Windows Subsystem for Linux)

WSL (Windows Subsystem for Linux) は、Windows10のOS上でLinux向けのバイナリプログラムを実行可能にする機能です。また、WindowsOSのAPIを用いた仕組みを提供しており、Linux側からWindowsOSへのファイルアクセスもできます。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

2クリップ

投稿2020/07/03 02:15

編集2020/07/03 03:36

やっていること

アセンブリを練習しています。
アーキテクチャ?は x86-64 で、環境は Windows10 64bit 上のWSL(Windows Subsystem for Linux)です。
(情報は十分でしょうか?)

発生している問題・エラーメッセージ

機械的に次のようなアセンブリを作成し、GCC にてアセンブラして実行すると、Segmentation Fault のエラーが発生します。
(長くて無駄なコードが多いので、後ろに手動で無駄なコードを若干削って、処理範囲ごとに適当に改行とコメントを入れたものも載せます。
C言語で該当するコードも載せます。)

assembly

1.intel_syntax noprefix 2.global main 3main: 4 push rbp 5 mov rbp, rsp 6 sub rsp, 0 7 push 2 8 push 1 9 pop rdi 10 pop rsi 11 call add 12 push rax 13 pop rax 14 mov rsp, rbp 15 pop rbp 16 ret 17 pop rax 18 mov rsp, rbp 19 pop rbp 20 ret 21 pop rax 22 23add: 24 push rbp 25 mov rbp, rsp 26 sub rsp, 16 27 mov rax, rbp 28 sub rax, 0 29 push rax 30 pop rax 31 mov [rax], rdi 32 mov rax, rbp 33 sub rax, 8 34 push rax 35 pop rax 36 mov [rax], rsi 37 mov rax, rbp 38 sub rax, 0 39 push rax 40 pop rax 41 mov rax, [rax] 42 push rax 43 mov rax, rbp 44 sub rax, 8 45 push rax 46 pop rax 47 mov rax, [rax] 48 push rax 49 pop rdi 50 pop rax 51 add rax, rdi 52 push rax 53 pop rax 54 mov rsp, rbp 55 pop rbp 56 ret 57 pop rax 58 mov rsp, rbp 59 pop rbp 60 ret 61 pop rax

無駄を手動で削ったもの:

assembly

1.intel_syntax noprefix 2.global main 3main: 4# プロローグ 5 push rbp 6 mov rbp, rsp 7 8# rdi 第一引数 9# rsi 第二引数 10# 関数呼出し 11 mov rdi, 1 12 mov rsi, 2 13 call add 14 15# エピローグ 16 mov rsp, rbp 17 pop rbp 18 ret 19 20add: 21# プロローグ 22 push rbp 23 mov rbp, rsp 24 sub rsp, 16 25 26# rdi の値を第一引数を表すスタックの位置へ代入 27 mov rax, rbp 28 mov [rax], rdi 29 30# rsi の値を第二引数を表すスタックの位置へ代入 31 mov rax, rbp 32 sub rax, 8 33 mov [rax], rsi 34 35# 二項 + 演算子の左オペランドの値([rbp])をスタックに積む 36 mov rax, rbp 37 mov rax, [rax] 38 push rax 39 40# 二項 + 演算子の右オペランドの値([rbp-8])をスタックに積む 41 mov rax, rbp 42 sub rax, 8 43 mov rax, [rax] 44 push rax 45 46# rdi = 右オペランド 47 pop rdi 48# rax = 左オペランド 49 pop rax 50# rax += rdi 51 add rax, rdi 52 53# エピローグ 54 mov rsp, rbp 55 pop rbp 56 ret

C言語版:

C

1int add (int, int); 2int main (void) { 3 return add(1, 2); 4} 5int add (int lhs, int rhs) { 6 return lhs + rhs; 7}

質問

なぜでしょうか?
解決方法を教えて下さい。
またこのように問題が発生した時のために、アセンブリのデバッグ方法も知りたいです。

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

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

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

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

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

cateye

2020/07/03 09:45 編集

えっと、リンクしてますよね?・・・・mainの呼び出しがないようですが?・・・後始末も。
tails

2020/07/15 00:51

リンクはしています。 このアセンブリは実行ファイル全体ではなく、単体のファイルで、リンクすることで実行可能ファイルに main の呼び出しが追加されています。 とりあえず main は呼べています。 エラーは「Segmentation Fault」であり、ある程度コードを削ると、エラーが消えるため。
guest

回答2

0

自己解決

assembly

1.intel_syntax noprefix 2.global main 3main: 4 push rbp 5 mov rbp, rsp 6 sub rsp, 0 7 push 2 8 push 1 9 pop rdi 10 pop rsi 11 call add 12 push rax 13 pop rax 14 mov rsp, rbp 15 pop rbp 16 ret 17 pop rax 18 mov rsp, rbp 19 pop rbp 20 ret 21 pop rax 22 23add: 24 push rbp 25 mov rbp, rsp 26 sub rsp, 16 27 mov rax, rbp 28 sub rax, 8 29 push rax 30 pop rax 31 mov [rax], rdi 32 mov rax, rbp 33 sub rax, 16 34 push rax 35 pop rax 36 mov [rax], rsi 37 mov rax, rbp 38 sub rax, 8 39 push rax 40 pop rax 41 mov rax, [rax] 42 push rax 43 mov rax, rbp 44 sub rax, 16 45 push rax 46 pop rax 47 mov rax, [rax] 48 push rax 49 pop rdi 50 pop rax 51 add rax, rdi 52 push rax 53 pop rax 54 mov rsp, rbp 55 pop rbp 56 ret 57 pop rax 58 mov rsp, rbp 59 pop rbp 60 ret 61 pop rax

自己解決しました。
スタックを動かして自動変数を確保していましたが、その参照先がベースポインタの位置と、lhsの位置になってしまっていました。
lhsの位置と、rhsの位置を指すようにすることで解決しました。

投稿2020/07/18 12:16

tails

総合スコア22

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

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

0

VisualStudioでデバッグできますよ

#Eclipseはどうだったかなあ。。

投稿2020/07/03 02:48

y_waiwai

総合スコア88042

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

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

tails

2020/07/03 04:09

Windows と Linux ではアセンブリ、キーワードがちょくちょく違うみたいなので、できれば WSL 上でデバッグしたいです… (キーワードを書き換えれば Visual Studio 上でできるとは思いますが、何分初心者ですので、「書き換えが間違い」なのか「コードが間違い」なのか、混乱してしまいます) https://kagasu.hatenablog.com/entry/2018/01/03/200337 こんな感じで出来るっぽい、というのは分かりました。
y_waiwai

2020/07/03 05:43 編集

まあ、Eclipseでもできると思います Cのmain関数からそのアセンブリルーチンを呼び出す形にしておけば、ステップ実行でそのコードの中まで追いかけられます。 そこでレジスタの値などをみていけばいいです
tails

2020/07/15 00:54

そうなんですね、ありがとうございます。 返信遅くなっていてすみません。 一行一行コードを削ったりして手動デバッグで解決してしまいました…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問