Cとアセンブリの混合プログラミング&&ELFファイルフォーマット解析


準備作業:Cとアセンブリの混合プログラミングELFファイルフォーマット解析、これは『自分でオペレーティングシステムを書く』第5章の準備作業であり、主にCとアセンブリの混合プログラミングのいくつかの知識を説明し、ELFファイルの関連知識を説明し、C言語でオペレーティングシステムを書く準備をする.
1.システムコールsys_についてwrite
Linuxのシステム呼び出しはint 80 hで実現され,dosの割り込みに類似した役割を果たすシステム呼び出し番号でエントリ関数を区別する.
      
        mov edx, len     ;    :     
        mov ecx, msg     ;    :       
        mov ebx, 1       ;    :     (stdout) 
        mov eax, 4       ;      (sys_write) 
        int 0x80         ;       

2.Cとアセンブリの混合プログラミング
2.1 64ビットマシン上のターゲットファイルの互換性の問題:「could not read symbols」
本の命令に従えば
nasm -f -o foo.o foo.asm gcc -c o bar.o bar.c ld -s -o foobar foo.o bar.o 64 bの機械にいたら「could not read symbols」というエラーメッセージが表示されます.これは、foo.o&&bar.oがそれぞれ32 bのターゲットファイルと64ビットのターゲットファイルなので、リンクを使用してリンクできません.解決方法:32 bのelfファイルを統一的に使用し、gcc-m 32-c-o bar.o bar.c ld-m elf_i 386-s-o foobar foo.o bar.o
2.2パラメータ伝達問題
アセンブリで定義された関数が外部プログラムに参照される場合は、キーワードでglobalをエクスポートする必要があります.
アセンブリに他のファイルで定義された関数が使用される場合は、関数を宣言し、externをインポートする必要があります.パラメータスタックの順序-後のパラメータがスタックに先に入る
3.ELFファイル形式解析
3.1.ELFファイルフォーマットを理解する必要がある理由
linux実行可能カーネルはELFファイル形式を採用しているため、ELF形式のカーネルをメモリにロードした後、どのようにカーネルに制御権を移行しますか?プログラムが実行を開始した開始場所がELFヘッダに対する位置をどのように知っていますか?カーネルをメモリにロードした後、プログラムはどのように実行しますか?プログラム実行時に使用されるのはすべて仮想アドレスであり、ELFファイルフォーマットで提供されるのはすべて仮想アドレスである.では、どのようにして対応する仮想アドレスにプログラムをロードしますか?ELFファイルフォーマットには多くの冗長情報が格納されており、プログラムにも多くの異なるセグメントが含まれています.では、これらのセグメントをそれぞれ異なる場所にロードするにはどうすればいいですか?プログラムヘッダは、ファイル内のオフセット、長さ、仮想アドレスにロードされた位置情報の合計数がいくつありますか?
など、ELFファイルのフォーマットを知る必要があります.
3.2 ELFファイルフォーマットの概要
1)ELFファイルのフォーマットを理解するには、バイナリファイルを表示する一般的なコマンドであるコマンド、xxdを熟知する必要があります.
一般的なパラメータの意味は次のとおりです.-u:大文字でコンテンツを表示します.-a:autoskipは空のデータを自動的にスキップします.-g num:groupbyパケットサイズ1は1バイト-c colsを表します:各行に表示される列数-l num:合計何セル-s+/-num:seekを表示し、開始セルがどのくらい離れた場所から表示を開始します2)elfファイルフォーマットと後続の関連部分
elfファイルの詳細については、ここを参照してください.elfファイルフォーマットの完全解析
次の情報が表示されます.
A.ELFファイルヘッダには、プログラムのエントリを含む仮想アドレス;
B、各セグメントのELFファイルにおける位置とサイズ情報、仮想メモリにロードされる位置とサイズ情報
4.呼び出し原理
まず,アセンブリ呼び出しC言語関数は実際にcall命令によって実現されることを知った.callのオブジェクトはシンボルテーブルのシンボルであり、実際には、このシンボルは仮想アドレス、すなわちシンボルテーブルのシンボルに対応し、仮想アドレスである.では、callとjmpの違いは何でしょうか.
jmpの違いは、1つはセグメント内呼び出しであり、1つはセグメント間呼び出しである.
callの呼び出しはスタックに影響を及ぼすため、callの呼び出しは大きく異なる:(1)callの近接呼び出しは使用するスタックを変更しないが、スタックの内容は変化した:次の命令はスタックに押し込まれる;パラメータがある場合、パラメータがスタック(2)callに押し込まれる遠隔呼び出しは、使用するスタックを変更し、使用するスタックが変化するため、パラメータに対してコピーのプロセスがある.現在のssとespを呼び出されたプロシージャのスタックに保存パラメータをコピー現在のcsとeipを呼び出されたプロシージャのスタックに保存
まとめ:callとjmpの主な違いは戻りアドレスの違いにある.call遠隔呼び出しと近接呼び出しの違いは,スタックssとspの情報を保存することである.