
(mainadd.c)
#include <stdio.h>
void intadd(int, int, int*);
void main()
{
int a,b,c;
printf("Enter a,b : ");
scanf("%d %d", &a, &b);
intadd(a, b, &c);
printf("Answer = %d\n", c);
}
(intadd.s)
.file "intadd.s"
.text
.align 4
.globl intadd
.type intadd,@function
intadd:
pushl %ebp
movl %esp, %ebp
bpoint1:
movl 16(%ebp), %ebx
movl 8(%ebp), %edx
addl 12(%ebp), %edx
movl %edx, (%ebx)
bpoint2:
#
movl %ebp, %esp
popl %ebp
ret
(comfile)
break main
display/i $pc
display/x $ebx
display/x $edx
display/x $esp
display/x $ebp
>gcc -m32 -o mainadd mainadd.c intadd.s
>gdb -x comfile mainadd
として、
a=1
b=2
を入力してデバッグを行うと、Cのprintf("Answer = %d\n", c);の中で、Segmentation faultがおきてしまいます。一応、以下に示すように%ebxが示すアドレス(cのアドレスが入っている)には、0x3(cの値)が正しく入っている様なのですが、何故か以下の箇所でSegmentation faultが起きてしまう理由が分かりかねています。似たようなご経験のある方で、アドバイス頂けると助かります。
(ここから途中からのデバッグ情報です)
0x56556030 in printf@plt ()
1: x/i $pc
=> 0x56556030 <printf@plt>: jmp *0xc(%ebx)
2: /x $ebx = 0xffffd834
3: /x $edx = 0x3
4: /x $esp = 0xffffd81c
5: /x $ebp = 0xffffd848
(gdb) si
0xffffd860 in ?? ()
1: x/i $pc
=> 0xffffd860: add %eax,(%eax)
2: /x $ebx = 0xffffd834
3: /x $edx = 0x3
4: /x $esp = 0xffffd81c
5: /x $ebp = 0xffffd848
(gdb) si
0xffffd862 in ?? ()
1: x/i $pc
=> 0xffffd862: add %al,(%eax)
2: /x $ebx = 0xffffd834
3: /x $edx = 0x3
4: /x $esp = 0xffffd81c
5: /x $ebp = 0xffffd848
(gdb) si
0xffffd864 in ?? ()
1: x/i $pc
=> 0xffffd864: hlt
2: /x $ebx = 0xffffd834
3: /x $edx = 0x3
4: /x $esp = 0xffffd81c
5: /x $ebp = 0xffffd848
(gdb) si
Program received signal SIGSEGV, Segmentation fault.
0xffffd864 in ?? ()
1: x/i $pc
=> 0xffffd864: hlt
2: /x $ebx = 0xffffd834
3: /x $edx = 0x3
4: /x $esp = 0xffffd81c
5: /x $ebp = 0xffffd848
(gdb) x/x $ebx
0xffffd834: 0x00000003
No.5
- 回答日時:
そうなってるんじゃないかなぁと想像はしてた.
スタックのどこにどのようなデータがあるのか, 図にしてみてみよう. そして「16(%ebp)」や「8(%ebp)」などがなにに対応しているのか, 元の質問文のプログラムと書き換えたあとのプログラムとでそれぞれ考えてみてください.
No.3
- 回答日時:
どのレジスタを壊してよくってどのレジスタを壊しちゃダメなのかは, 調べればわかるはず. 通常 edx は壊しても問題ないんだけど, 「どんなシステムでも問題ない」とはいわないので調べてくれ.
あと, 「ebx をぶち壊した」のがなぜ敗因なのかは理解できているんですよね?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語の勉強しています。すみま...
-
C言語プログラミング
-
boolean型の戻り値は可能か
-
最早開始時間と最遅完了時刻を...
-
【C++】関数ポインタの使い方
-
既定のコンストラクタがありま...
-
Aの値からBの値を除するとは??
-
「Aに対するBの割合」と「Aに対...
-
信頼区間の1.96や1.65ってどこ...
-
a^2の√=a が成り立たない場合
-
VB6.0での小数点の扱いについて
-
配列をnビットシフトする
-
数学 一次関数 関数 y=-3/4x+k(...
-
c languageで 簡単な質問があ...
-
C言語 エラーの原因がわからな...
-
#define _CRT_SECURE_NO_WARNIN...
-
プログラムでの数字につく”f”の...
-
C言語で複数列のデータを1列の...
-
c言語で、繰り返し文の中で、0....
-
sscanfとscanfの違いがよくわか...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
10個出力で改行したいのですが...
-
コンパイルエラーについて
-
CTRL+Dでループを抜けるには
-
Cプログラムについて
-
コマンドラインに出力した文字...
-
WM_CLOSEで閉じれないウィンド...
-
C言語の&に関する質問
-
すごろくに使用するサイコロ
-
文字と数字の判定について
-
printf( " %2d", p * q );
-
【C言語教えてください】sin波...
-
%P と %X の違い
-
C言語の勉強しています。すみま...
-
strcmp
-
c言語でAからZまでを表示する...
-
unsigned int型について
-
(C言語)めちゃくちゃな値にな...
-
printf で二進表示を行いたい。
-
プログラミング C言語 課題でプ...
-
c言語で2000年以降カレンダーを...
おすすめ情報
movl $ebp, %esp
で行っていると思うのですが。
ただ、この場合は、
mov $esp, %ebp
以下で$espの値は変更していません。
ecxかedxを使うと言うことですか?
(1)ebx -> ecx
にするとOKになるのですが、
(2)ebxをそのまま使って、
pushl %ebp
pushl %ebx
.
.
.
popl %ebx
popl %ebp
ret
としても動きそうに思うのですが、Segmentation fault
になってしまうようなのですが、どうしてなのでしょうか?
intadd:
pushl %ebp
push %ebx
movl %esp, %ebp
bpoint1:
movl 16(%ebp), %ebx
movl 8(%ebp), %edx
addl 12(%ebp), %edx
movl %edx, (%ebx)
bpoint2:
#
movl %ebp, %esp
pool %ebx
popl %ebp
ret
intadd:
pushl %ebp
push %ebx
movl %esp, %ebp
bpoint1:
movl 20(%ebp), %ebx
movl 12(%ebp), %edx
addl 16(%ebp), %edx
movl %edx, (%ebx)
bpoint2:
#
movl %ebp, %esp
pool %ebx
popl %ebp
ret