以下のfuncTest.cを、
int add(int a, int b) {
int array[16];
array[0] = a;
return a + b;
}
void func(void) {
int r;
r = add(7, 5);
}
gcc -c -m32 funcTest.c
でコンパイルし、funcTets.oのオブジェクトファイルを生成し、
objdump -d funcTest.o
で逆アセンブルすると、以下の出力となるのですが、
funcTest.o: file format elf32-i386
Disassembly of section .text:
00000000 <add>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 40 sub $0x40,%esp
6: e8 fc ff ff ff call 7 <add+0x7>
b: 05 01 00 00 00 add $0x1,%eax
10: 8b 45 08 mov 0x8(%ebp),%eax
13: 89 45 c0 mov %eax,-0x40(%ebp)
16: 8b 55 08 mov 0x8(%ebp),%edx
19: 8b 45 0c mov 0xc(%ebp),%eax
1c: 01 d0 add %edx,%eax
1e: c9 leave
1f: c3 ret
00000020 <func>:
20: 55 push %ebp
21: 89 e5 mov %esp,%ebp
23: 83 ec 10 sub $0x10,%esp
26: e8 fc ff ff ff call 27 <func+0x7>
2b: 05 01 00 00 00 add $0x1,%eax
30: 6a 05 push $0x5
32: 6a 07 push $0x7
34: e8 fc ff ff ff call 35 <func+0x15>
39: 83 c4 08 add $0x8,%esp
3c: 89 45 fc mov %eax,-0x4(%ebp)
3f: 90 nop
40: c9 leave
41: c3 ret
Disassembly of section .text.__x86.get_pc_thunk.ax:
00000000 <__x86.get_pc_thunk.ax>:
0: 8b 04 24 mov (%esp),%eax
3: c3 ret
以前は、
6、b行の
call 7 <add+0x7>
add $0x1,%eax
と、
26、2b行の
call 27 <func+0x7>
add $0x1,%eax
が無くて、
34、39行の
call 35 <func+0x15>
add $0x8,%esp
が、
call 0 <add>
となって、
call命令で<add>の最初の命令を呼び出していたのですが、
何故、この様な出力になってしまったのか分かりかねています。
どなたか分かる方、御教示おください。
No.3ベストアンサー
- 回答日時:
オブジェクトファイルを逆アセするんじゃなくって, gcc に直接アセンブリ出力を出させれば 3つのうち 1つは意味がわかる.
あと, 自分で調べることも必要だと思う.
調べてみたんですけど、gccはデフォルトで、-O0オプションとなるようで、
この場合、コンパイラが「位置に依存しない」実行可能ファイルを生成するみたいです。
call __x86.get_pc_thunk.ax
はそのための「グローバルポインタ」を設定するためのものの様です。
これは、
-fno-pie
オプションをつけることで、位置に依存しない形で無くすことができる様です。
また、callの後の、
add $0x8, %esp
はfuncのスタックフレームの上限のスタックポインタの位置を仮引数を渡すために使った、5と7の2個はもう必要ないので、+8しているみたいです。
No.5
- 回答日時:
うん, そこの
fc ff ff ff
は現状「バイトを埋める」だけのダミーで, 最終的にはその飛び先である関数 add の先頭アドレス (の相対値) が入ることになる. それを入れるのはリンカかローダーのどっちかなんだけど, この場合どっちなんだろう.
そもそも同じオブジェクトファイルの中で呼んでいるだけだから, そこをダミーにする必然性はないわけだけど.
あと, 念のため改めて書いておくけどこの辺の話は C という言語とは関係なくって, 使っているシステムに依存することだからね. ここではたまたまあなたが C を使っていて疑問に思ったというだけであって, 「C だったらどのシステムでも同じようになっている」というわけではないよ.
No.4
- 回答日時:
「デフォルトで最適化オプション -O0 がつく」ことと「PIC なコードを吐く」こととは無関係だよ. -O0 以外の最適化オプショ
ンでも, -fno-pie オプションを付けないと PIC なコードになる.call 35 <func+0x15>
って、この位置のfc ff ff ffに
<add>の飛び先番地が入るってことなのですかね?
No.2
- 回答日時:
そこまで細かい話は当然ながら C の規格では一切触れられていないので, 本当に理由を知りたければ最低限「あなたが使っているシステムの詳細」は必須だろう. 「以前」のシステムはどうであって, 「今」のシステムはどうなのか, その情報がなければ答えようがない.
もちろんそれらの情報があれば確実に (誰かが) 答えてくれる, というものでもないわけだが.
あるいは, オブジェクトファイルを使わず gcc にアセンブリ出力を直接出させてみるとか.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# アセンブラ指令 3 2023/06/17 14:47
- その他(プログラミング・Web制作) x86_32のGASの擬似命令 3 2023/06/07 19:55
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- JavaScript アップロードファイルの種類によって処理を分岐させたいのですが書き方が分からずアドバイスお願いします 4 2023/06/17 19:12
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- オープンソース stable diffusionのインストールがうまくいきません。 1 2023/06/20 13:09
- その他(プログラミング・Web制作) python 2 2022/12/23 09:06
- C言語・C++・C# C言語 ポインタ 配列 2 2022/06/02 17:29
- Visual Basic(VBA) 【Excel VBA】自動メール送信の機能追加 5 2022/09/29 12:53
- その他(ソフトウェア) Microsoft Store Guitar Pro購入後の質問 1 2022/08/11 17:15
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# で 数式文字列処理を処理す...
-
大量のデータを読み込んで表示...
-
C言語のことです。写真(見にく...
-
10進数からN進数に変換するプロ...
-
c言語
-
c#のTLS1.2での通信について
-
プログラミングでArduinoのc++...
-
C#でログファイルにファイルパ...
-
プログラミング言語の制作方法...
-
visual studioでフォームデザイ...
-
C#でTreeViewのCheckBoxのサイ...
-
c言語
-
0 == False はいいけど
-
c言語の問題の説明、各所ごとに
-
スタックフレームの消滅
-
これて逆じゃないですか?
-
バッチファイルで以下のような...
-
Stuck
-
c言語
-
VisualStudioで、コードを印刷...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c++の勉強方法を教えてくださ...
-
プログラミング言語でアプリや...
-
c言語
-
大量のデータを読み込んで表示...
-
Cのプログラムからアクセスでき...
-
gccを行ってもexeファイルが生...
-
Windows Formアプリからコンソ...
-
C#でログファイルにファイルパ...
-
写真のプログラムは、1からnま...
-
VisualStudioでC++クラスを追加...
-
VisualStudio2022でC言語プログ...
-
【C言語】全角文字の配列を、全...
-
逆コンパイルと逆アセンブルの...
-
MACで動く実行ファイルをWindow...
-
C言語 1から20までの逆数の和を...
-
C#でTreeViewのCheckBoxのサイ...
-
C++でデスクトップGUIアプリ開...
-
c言語でイベントフラグを使った...
-
これて逆じゃないですか?
-
const char** p;のとき、free(p...
おすすめ情報
リリースモードでコンパイルした場合、
gcc -c -m32 funcTest.c
はどの様に書けばいいのでしょうか?
3つのcall命令は何をしているか分かりますか?
それは既にやっているのですが、
何故、最後のcall命令だけが、call add
になって、それ以外の2つが、
call __x86.get_pc_thunk.ax
になるんですかね?
また、__x86.get_pc_thunk.axに飛んで行っている、
move (%esp), %eax
って何をやっているんでしょうか?
また、call命令を行った後の、
addl $_GLOBAL_OFFSET_TABLE_, %eax
や
addl $8, %esp
も何をやっているんでしょうね?