CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

Cygwin環境でGCC(3)

「__main」について調べてみると、どうもこれは主関数mainを呼ぶ前にメモリの初期化、
コードのコピーを行うライブラリ内関数のようです
 
 __main はメモリをセットアップし、__rt_entry はランタイム環境をセットアップします。
 __main によって、コードとデータのコピー、伸張、および ZI データのゼロ初期化が実行されます。 次に、__rt_entry に分岐して、スタックとヒープのセットアップ、ライブラリ関数と静的データの初期化、およびトップレベルの C++ コンストラクタの呼び出しが行われ 
 ます。その後、__rt_entry は、アプリケーションのエントリである main() に分岐します。 メインアプリケーションの実行が終了すると、__rt_entry によってライブラリがシャットダウンされ、制御がデバッガに戻されます。
 関数ラベル main() には特別な意味があります。 main() 関数が存在することにより、リンカは __main および __rt_entry 内の初期化コードをリンクします。 main() 関数が存在しない場合は、初期化シーケンスがリンクされず、その結果、標準 C ライブラリの一部の機能がサポートされなくなります。
 
イメージ 4
 
ライブラリのソースを検索するとlibgcc2.cの中にその実体がありました。
main()のためのコンストラクタとして作用するようですが、モニタのメモリ環境を継承して永久ループする組込み用途では不要と割り切ります

イメージ 1
 
対処としては中身が空の__main()を自前で作ってしまえばリンクエラーはなくなります
 
イメージ 2
 
でももっと簡単にやるには
__main()は特殊な関数ラベルmain()においてのみ挿入されるので
主関数としてmain()の名前を使わなければいいわけです
主関数の名前を_main()・・・まぎらわしいですがアンダースコア1個
としてコンパイルすると余計なコンストラクタ呼び出しがなくなります

イメージ 3

startupルーチンからの呼び出しラベルも_mainにしておきます