私は一例でアセンブリ言語を習得しようとしている、または-Sオプションを使用してGCC、インテルの構文を使用して簡単なCファイルをコンパイルし、CFIが無効に呼び出していますが、(他のすべての自由な方法が非常に混乱してGCCは、コンパイル済みのアセンブリ
マイC ?ファイルは、文字通りint main() {return 0;}
ですが、GCCは、この吐く:
.file "simpleCTest.c"
.intel_syntax noprefix
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
push ebp
mov ebp, esp
and esp, -16
call ___main
mov eax, 0
leave
ret
.ident "GCC: (GNU) 5.3.0"
私の本当の問題は、なぜ主な機能は、任意のプロセッサ命令(push edp
、mov edp, esp
、など)を持っているんですが、これらは必要さえあります(私はそれは次のようになり推測プログラムを準備/シャットダウンするためのデータ管理の方法ですが、わかりません)なぜ? main関数のあとにret
ステートメントを発行してもかまいませんか?また、なぜ2つの主な機能(_main & ___main)がありますか?
これを要約すると、なぜこのようなものではないのですか?
.def _main
_main:
mov eax, 0 ;(for return integer)
ret
( '-O2')で最適化を有効にします。 'main'は特別なことに注意してください。' int foo(){return 0;} 'を実行する方が良いかもしれません。また、コンパイラ生成コードを理解しようとすることは必ずしも容易ではありません。 – Jester
あなたはWindowsのようですか?その理由は、 '___ main'が呼び出されるのは、登録された静的コンストラクタを呼び出すためです。 'とesp、-16'は' ___ main'を呼び出す前にスタックが16バイト整列していることを確認することです。 esp/ebp/leaveは、スタックフレーム用の標準的なボイラープレートコードです。デバッガで使用したときにスタックの巻き戻しデータがなくても便利ですが、必須ではありません。 –
[x86タグwiki](http://stackoverflow.com/tags/x86/info)に興味深いリンクがいくつかあります。 –