0

16 ビット プロテクト モード、具体的にはいくつかのプログラムを含む単純なオペレーティング システム用のコードを書きたいと考えています。ばかげているように聞こえるかもしれませんが、これらの制約の下でプログラムを作成する方法を理解することに興味があります。

16 ビット プロテクト モードで動作するさまざまなオペレーティング システム (OS/2 や Win 3.1 など) で採用されている規則の種類を知りたいです。彼らはどの ABI を使用しましたか? farポインタはどのように渡されますか? コード モデルごとに複数の ABI がありましたか?

明確にするために、私は far ポインターとは何か、API レベルでどのように使用されるかを知っています。私が知りたいのは、これがアセンブリレベルでどのように機能するかです。far ポインターのセグメントはスタックに渡されますか? 特別な規則はありますか?

4

2 に答える 2

2

ほとんどの 16 ビット プロテクト モード API は、パラメーターとして far ポインターを受け取りました。far ポインターは、16 ビットのオフセット (下位ワード) と 16 ビットのセレクター (上位ワード、セレクターはセグメントを参照) の両方を含む 32 ビットの値です。他のパラメーターと同様に、スタックに置くことで値渡しされます。通常、これらのポインタは最大 65536 バイトのメモリ領域しか参照できませんでしたが、別の far ポインタは別のメモリ領域を参照でき、64K を超えるメモリを使用できました。

たとえば、16 ビット Windows API (Win16) では、関数GetClientRectには次の文書化されたインターフェイスがありました。

void GetClientRect(hwnd, lprc)

HWND hwnd;    /* handle of window */
RECT FAR* lprc;   /* address of structure for rectangle   */

シンボルは、16 ビット Windows API の使用時にキーワードにFAR展開されるマクロでした。far現在、この API 関数はLPRECT、「RECT への長い (遠い) ポインター」として読み取られることを意図したパラメーターを取るものとして文書化されています。シンボルは、32 ビットおよび 64 ビット Windows APILPRECTの typedef として定義されています。16 ビット API がまだサポートされている場合は、それを使用するときRECT *の typedef になります。RECT far *

farポインター (および関数自体) でキーワードを使用しているため、すべてのメモリ モデルから API にアクセスできたため、メモリ モデル (小、中、コンパクト、大) ごとに個別の API はありませんでした。コンパイラは、それが far ポインターを受け取ったことを確認し、必要に応じて Near (16 ビット) ポインターをプロモートします。

于 2015-05-06T16:01:01.483 に答える
1

80286 アーキテクチャの AT システムが導入された昔から覚えている限り、メモリは 64 KB セグメントで構成されていました。これは、16 ビット アドレス レジスタ (リアル モード) を使用してアドレス指定できる最大アドレスです。コーディングがアセンブリで行われた場合、ニア ジャンプとファー ジャンプは、それぞれセグメント内またはセグメント外で発生する可能性があります。ファー ジャンプが発生した場合、アセンブリでは、最初にジャンプが発生するセグメントを指定し、次にセグメント内のローカル アドレスを指定する必要があります。

プロテクト モードでは、ディスクリプタ テーブルを使用してセグメントのアドレス範囲を拡張し、マシンで使用できるメモリの量を増やすことができました。

コードが再入可能になるように実装されていれば、適切な BIOS および OS 割り込みを使用して、マルチタスクおよび TSR (Terminate and Stay Resident) プログラムを実装できます。

于 2015-05-06T16:16:42.033 に答える