2

結局のところ、私たちが書いたすべてのコードは、最終的にアセンブラーに変換され、次に機械語に変換されます。

アセンブラーを作成していて、2 台のコンピューター間で単純な接続を実行したい場合、アセンブラー内で使用するメモリ アドレス (オフセットは言うまでもなく) をどのように知るのでしょうか? オペレーティング システムに関連する特定のアドレスを知る必要がありますか?

誰かが本当に「クリーン」で「効率的な」メッセージ パッシング ライブラリ/コンパイラをどのように作成するのか疑問に思っています。

この答えの一部は、OSに関連する既知のアドレスを照会することにあると思いますか? たとえば、0x4545456 から 0x 60000000 には、通信 X などの Linux カーネル データが含まれます。

4

2 に答える 2

1

アドレスはOSに固有のものではありません。それらはハードウェア/システムに固有です。これらへのアクセスは、アセンブラーと別のプログラミング言語(Cなど)とは関係ありません。実際、ほとんどのデバイスドライバーコード(ネットワークハードウェアと実際に対話するコード)は通常、Cで記述されています。

ネットワーク(イーサネット)コントローラーのランダムサンプルを1つだけ示します。

インテル®82580EB/82580DBGbEコントローラー:データセット

アセンブラまたは別の言語のソフトウェアが、イーサネットを介して実際に通信するためにプログラムする必要のあるレジスタがたくさんあります。シリアルポートのような単純な例から始める方がおそらく簡単です。メモリにマッピングされた、架空の固定ボーレートのシリアルポートコントローラを作成してみましょう。

Address  Meaning
0        RX status (reads 0 when no data to read, 1 a byte is available)
1        RX buffer
2        TX status (reads 0 when ready to send, 1 when busy)
3        TX buffer

これで、ソフトウェアは、アセンブラまたは他の言語で、アドレス2を監視(ポーリング)して準備が整うまでデータを別のコンピュータに送信し、次のバイトをアドレス3に書き込むことができます。監視(ポーリング)によって別のコンピュータからデータを受信することもできます。 )アドレス0は、データの準備ができているかどうかを確認し、データがそこにあるときにアドレス1からバイトを読み取ります。

最新のオペレーティングシステム/OSでは、これらはすべて物理アドレスであり、何らかの方法で仮想アドレスにマッピングする必要があります。

私がリンクしたような実際のハードウェアは通常、割り込みを使用するため、ポーリングする必要はありません。通常はDMAが搭載されているため、ハードウェアはデータをバイト単位でフィードするのではなく、データに直接アクセスできます。さまざまなプロトコルを処理し、このプロトコルのさまざまな側面をチェックおよび設定するためのレジスタを備えています。

最新のOSでは、ハードウェアとの実際の相互作用はデバイスドライバーに実装されており、ユーザーソフトウェアはAPIを介してデバイスドライバーとデータを交換できます。この場合も、このユーザーコードはアセンブラーまたはその他の言語で記述できます。APIはOSによって異なります。通信/ネットワーキングは通常、「スタック」として構築され、低レベルのプロトコルの上に高レベルのプロトコルが実装されます。このスタックのどの部分がユーザーライブラリにあるか、またはOSの一部にあるかは、オペレーティングシステムによって異なります。

上記で説明した架空のデバイスの場合、APIは2つのシングルバイトブロッキング呼び出しで構成されている可能性がありread()ますwrite()。次に、アセンブラまたは高級言語のいずれかからのある種のシステムコールメカニズムを使用して、これらを呼び出し、パラメータを渡したり、出力を取得したりします。一部のオペレーティングシステムでは、デバイスI/OがファイルI/Oのように見える場合があるため、汎用ファイルの読み取り/書き込みを使用してデバイスで操作を実行すると、OSがそれらを適切なデバイスドライバーにディスパッチします。さらに、一般的なOSでは、実際のシステムコールは、さまざまなプログラミング言語から呼び出すことができる、ある種のライブラリを介して利用できます。

于 2012-04-08T20:00:22.620 に答える
1

アセンブリでネットワークを実行するための2つのコードがあります。オペレーティングシステムが実際にネットワークを実行するために使用するカーネルコードと、ネットワークを介して送信するデータをOSに通知するクライアントコードです。

通常、マシンのハードウェアには、ネットワークハードウェアとの通信専用の特定のメモリアドレスがあります。次に、OSのマシンコードが適切な値をこのメモリに書き込んで、最終的にバイトを送受信するハードウェアを制御できます。これらのメモリアドレスは、マシンコードにハードコードされます。

ネットワーキングを行うユーザーコード(Mozilla Firefoxなど)の場合、プロセスは異なります。通常、オペレーティングシステムに何らかのタスクを実行するようにユーザーコードに指示するために使用されるマシン命令または一連の命令があります(たとえば、MIPSでは、これはですがsyscall、x86はint命令)。クライアントコードは、ネットワークに送信する適切なデータを使用していくつかのバッファを設定することで機能し、次に上記のアセンブリ手順の1つを使用して、データを送信する必要があることをOSに通知します。次に、ハードウェアはOSを呼び出し、OSはユーザーデータを読み取り、独自のマシンコード(上記)を使用して実際にネットワークデバイスを適切に制御します。このように、OSは、デバイスを制御する物理アドレスへのアクセスをブロックし、システムコールによるアクセスをモデレートすることにより、ネットワークデバイスへの直接アクセスを保護できます。また、ネットワーキングを行うためのユーザーコードを作成するときに、メモリアドレスを知る必要がないことも意味します。OSはこれらの詳細を処理します。知っておく必要があるのは、システムコールをトリガーするために実行する命令だけです。

お役に立てれば!

于 2012-04-08T19:34:21.587 に答える