私はC/C ++とASMに戻ってきたので、少し火遊びをしたいと思っています。コードをコンパイルしてWindowsの実行可能ファイルにリンクすると、そのアプリケーションの実行が予想される任意のコンピューターに存在する必要のあるいくつかのライブラリに動的にリンクされることがわかりました。それらに対してリンクしないようにコンパイラーを指定し、そのための独自のライブラリーを作成することができます。
それとは別に(そして、ここで言うすべてが間違っている場合は訂正してください)、アプリのメインコードに沿って常にコンパイルおよびリンクされているオブジェクトファイルがあります。これはcrt0.o(Cランタイム)ファイルであり、私が知っているように、スタックを準備し、argcとargvを取得して、main関数(およびおそらく他のもの)を呼び出します。また、アプリケーションを実行するときにシステムによって呼び出される最初のコードだと思います。
だから、私は単純なcrt0.objを作成し、それを単純なC++オブジェクトファイルにリンクしようとしています。
int main(int argc, char** argv) {
return 0;
}
私はGCCを使用していますが、標準ライブラリを使用したくないので、コマンドは次のようになります。
g++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe crt0.o
-nostartfilesディレクティブは、リンカーにデフォルトのcrt0.oを埋め込まないように指示するものであると思います。そのため、関数のすべての定義を指定し、アプリケーションの起動を処理する必要があります。私はここで少し混乱しています。
とにかく、非常に基本的なcrt0オブジェクトファイルを作成したいと思います。これは、GCCが実行可能ファイルを作成し、システムがそれを開始するのに十分です。インターネット上には多くのコードファイル(CとASM)があることは知っていますが、それがどのように機能するかを学ぶために自分で作成したいと思います。私が必要としているのはコード以上のものであり、それを達成するために何をしなければならないか、そしてどのようにコンパイル/リンクするかについての少しの助けです。あなたがまた非常に高く評価されている有用なリンクを知っているなら。
私の疑問は次のとおり
です。1。コンパイラ/リンクはコードとCランタイムから最終ファイルをどのように作成しますか?crt0.oから(externディレクティブを使用して)main関数を呼び出す必要がありますか?実行するg++ -s -nostartfiles -nodefaultlibs -nostdlib testapp.cpp -o test.exe
と、「* undefined reference to__main*」エラーが発生します。main関数はcrt0.oファイルで定義されていますか?int main
変更しint start
てもエラーが出ないのは不思議です。どういう意味ですか?
2. crt0に含める必要のある重要な操作(コマンドライン引数の取得、mainの呼び出しなど)はどれですか?
3.私のコードファイルはCPPであり、crt0はCファイル(GCCでコンパイルされた)内のアセンブリの一部です。見つけて部分的に理解した作品から作成した「フランケンコード」を投稿します。
// crt0.c
__asm(".section .text\n"
".global _start\n"
"_start:\n"
"mov $0, %ebp\n"
"push %ebp\n"
"mov %esp, %ebp\n"
"push %esi\n"
"push %edi\n"
"call _init\n"
"pop %edi\n"
"pop %esi\n"
"call main\n"
"movl %eax, %edi\n"
"call exit\n"
".section .init\n"
".global _init\n"
"_init:\n"
"push %ebp\n"
"mov %esp, %ebp\n"
".section .fini\n"
".global _fini\n"
"_fini:\n"
"push %ebp\n"
"mov %esp, %ebp\n");
4.)そこで、このファイルでは、初期化関数をいくつか呼び出しました。init関数とfini関数はすでに作成されています(単純なコンストラクタとデストラクタのように見えますが、わかりません)。main関数もありますが、.cppmain関数とどのように関連しているかはわかりません。つまり、私はそれをインポートすることになっていますか?undefined reference
main関数とexit関数の両方でエラーが発生します。
5.)システムがその開始を見つけるために、c0は特定の形式を持っているか、特定の機能を含んでいる必要がありますか?
さて、小さなcrt0を作成し、コンパイラにそれを実行可能ファイルにアタッチさせるのは難しいとは思いませんが、正しく表示できないことがいくつかあります。誰かが私がこれらすべてを組み合わせるのを手伝ってくれることを願っています。ありがとう