やっていること
アセンブリを練習しています。
アーキテクチャ?は x86-64 で、環境は Windows10 64bit 上のWSL(Windows Subsystem for Linux)です。
(情報は十分でしょうか?)
発生している問題・エラーメッセージ
機械的に次のようなアセンブリを作成し、GCC にてアセンブラして実行すると、Segmentation Fault のエラーが発生します。
(長くて無駄なコードが多いので、後ろに手動で無駄なコードを若干削って、処理範囲ごとに適当に改行とコメントを入れたものも載せます。
C言語で該当するコードも載せます。)
assembly
.intel_syntax noprefix .global main main: push rbp mov rbp, rsp sub rsp, 0 push 2 push 1 pop rdi pop rsi call add push rax pop rax mov rsp, rbp pop rbp ret pop rax mov rsp, rbp pop rbp ret pop rax add: push rbp mov rbp, rsp sub rsp, 16 mov rax, rbp sub rax, 0 push rax pop rax mov [rax], rdi mov rax, rbp sub rax, 8 push rax pop rax mov [rax], rsi mov rax, rbp sub rax, 0 push rax pop rax mov rax, [rax] push rax mov rax, rbp sub rax, 8 push rax pop rax mov rax, [rax] push rax pop rdi pop rax add rax, rdi push rax pop rax mov rsp, rbp pop rbp ret pop rax mov rsp, rbp pop rbp ret pop rax
無駄を手動で削ったもの:
assembly
.intel_syntax noprefix .global main main: # プロローグ push rbp mov rbp, rsp # rdi 第一引数 # rsi 第二引数 # 関数呼出し mov rdi, 1 mov rsi, 2 call add # エピローグ mov rsp, rbp pop rbp ret add: # プロローグ push rbp mov rbp, rsp sub rsp, 16 # rdi の値を第一引数を表すスタックの位置へ代入 mov rax, rbp mov [rax], rdi # rsi の値を第二引数を表すスタックの位置へ代入 mov rax, rbp sub rax, 8 mov [rax], rsi # 二項 + 演算子の左オペランドの値([rbp])をスタックに積む mov rax, rbp mov rax, [rax] push rax # 二項 + 演算子の右オペランドの値([rbp-8])をスタックに積む mov rax, rbp sub rax, 8 mov rax, [rax] push rax # rdi = 右オペランド pop rdi # rax = 左オペランド pop rax # rax += rdi add rax, rdi # エピローグ mov rsp, rbp pop rbp ret
C言語版:
C
int add (int, int); int main (void) { return add(1, 2); } int add (int lhs, int rhs) { return lhs + rhs; }
質問
なぜでしょうか?
解決方法を教えて下さい。
またこのように問題が発生した時のために、アセンブリのデバッグ方法も知りたいです。
まだ回答がついていません
会員登録して回答してみよう