プログラムセグメントプレフィックス(PSP)は、 DOSシステムでプログラムの状態を格納するために使用されるデータ構造です。これは、CP/Mオペレーティングシステムのゼロページに似ています。PSPの構造は次のとおりです。
PSPは、 DOSプログラムのコマンドライン引数を取得するために最もよく使用されます。たとえば、コマンド「FOO.EXE /A /F」は、引数「/A」と「/F」を指定してFOO.EXEを実行します。
コマンドラインの長さを表す PSP エントリがゼロ以外で、環境セグメントへのポインタが 0000h または FFFFh のいずれでもない場合、プログラムは PSP からコマンドラインを抽出する前に、まず環境変数%CMDLINE%からコマンドラインを取得する必要があります。こうすることで、126 文字を超えるコマンドラインをアプリケーションに渡すことが可能になります。
PSPのセグメントアドレスは、プログラム実行時にDSレジスタに渡されます。また、Int 21h関数51hまたはInt 21h関数62hを使用して後で決定することもできます。どちらの関数も、PSPアドレスをレジスタBXに返します。[ 6 ]
あるいは、オフセットにロードされた.COMプログラムでは100h、上記のオフセットを使用するだけで PSP に直接アクセスできます。オフセットは000hPSP の先頭を指し、0FFhオフセットは末尾を指します。
例えば、次のコードはコマンドライン引数を表示します。
org 100h ; .COM - ds は使用していません; INT 21h サブ関数 9 は文字列の終了に '$' を必要としますxor bx , bx mov bl ,[ 80h ] cmp bl , 7Eh ja exit ; オーバーフローを防止mov byte [ bx + 81h ], '$'; 文字列を出力しますmov ah , 9 mov dx , 81h int 21hexit: mov ax , 4C00h ; サブ関数 4C int 21hDOS 1.x では、プログラム終了時に CS (コードセグメント) レジスタが PSP と同じセグメントを保持している必要があったため、標準的なプログラミング手法では、プログラム開始時に DS レジスタ (DS レジスタには PSP セグメントがロードされるため) とゼロワードをスタックに保存し、RETF 命令でプログラムを終了させていました。RETF 命令は、スタックから保存されたセグメント値をポップし、INT 20h 命令を含む PSP のアドレス 0 にジャンプします。
; 保存push ds xor ax , ax push ax; デフォルトのデータグループ(@data)に移動mov ax , @ data mov ds , ax; mess1 にメッセージを表示する (21h サブ関数 9) mov dx , mess1 mov ah , 9 int 21hretf実行ファイルが .COM ファイルの場合、この手順は不要で、INT 20h 命令を直接実行するか、INT 21h 関数 0 を呼び出すだけでプログラムを終了させることができました。ただし、プログラマはプログラム終了時に CS レジスタに PSP のセグメント アドレスが含まれていることを確認する必要がありました。したがって、
ジャンプ開始mess1 db 'Hello world!$'開始: mov dx , mess1 mov ah , 9 int 21h国際20時間DOS 2.x以降では、プログラムの終了は代わりにINT 21h関数4Chによって行われ、CSレジスタにPSPのセグメント値が含まれている必要はありませんでした。
[…]
CP/M-86
へのアクセス[…] CP/M-86 にアクセスするには、関数コードを CL レジスタに配置し、バイト パラメータを DL レジスタに配置するか、ワード パラメータを DX レジスタに配置し、データ セグメントを DS レジスタに配置し (データ セグメントは通常、変換されたプログラムでは変更されません)、ソフトウェア割り込み
INT #224
を実行する必要があります。結果がバイト値の場合は AL レジスタに返され、結果がワード値の場合は AX レジスタと BX レジスタの両方に返されます。ダブル ワード値は、オフセットが BX レジスタに、セグメントが ES レジスタに返されます。したがって、
CP/M-80から CP/M-86 へのプログラムの変換には、ロケーション 5 への呼び出しをソフトウェア割り込み INT #224 に置き換える必要があります。もう 1 つの必要な変更は、
ウォーム ブート
です
。 CP/M-80 では、ウォームブートは、ロケーション 0 へのジャンプのための機能コード 0 を持つシステムコールによってアクセスできます。しかし、CP/M-86 はロケーション 0 へのジャンプをサポートしていません。そのため、プログラムが正しく実行されるようにするには、翻訳されたプログラムでこのプログラム終了を変更する必要があります。ロケーション 5 への呼び出しが INT #224 に置き換えられ、ウォームブートの変更が行われ、レジスタが正しくマッピングされていれば、翻訳されたプログラムが CP/M-86 システム機能にアクセスできるようになることにほとんど問題はないはずです。 […]
MS-DOS
へのアクセス[…] MS-DOS には、システムにアクセスするためのソフトウェア割り込み
INT #33
を介した「推奨」メカニズムがありますが、少なくとも 0-36 の範囲の機能については、CP/M-80 呼び出し規約と互換性のある「既存の」プログラム用の追加のメカニズムが提供されています。許可された関数範囲内のシステムコールに関しては、プログラマはレジスタを正しくマッピングする以外に、MS-DOS上でプログラムを実行するために翻訳プログラムに対して何もする必要はありません。MS-DOSはCP/M-80のウォームブート機能もサポートしています。MS-DOSでアドレス0にジャンプすると、ソフトウェア割り込み
INT #32が実行されます。
これは機能的にはプログラムの終了であり、プログラムを終了する通常の方法です。[…](13ページ)
{{cite newsgroup}}: CS1メンテナンス: アーカイブサービスは非推奨になりました (リンク)(注:DOS COMプログラムの呼び出し規約に関する詳細情報が含まれています。)[…]
86-DOS
、そして
PC DOS
/
MS-DOS
は巧妙なトリックを使っていた。PSP のオフセット 5 のバイトには遠方呼び出しオペコード (9Ah) が含まれていた。PSP のオフセット 6 のワードには、プログラムセグメントサイズを示す適切な値と、遠方呼び出しのオフセット部分が含まれていた。遠方呼び出しのセグメント部分として機能するオフセット 8 のワードは、オフセットと組み合わせるとラップアラウンド (
8086
CPU のよく知られた機能) して、割り込みベクタ 30h を含むアドレス 0:C0h を指すように設計されていた。 […]
CALL 5
インターフェースは、Windows NT および OS/2 上の DOS エミュレーションでも動作します。これらのシステムは、
A20 ラインを
無効にした状態では絶対に動作しません。では、これはどのように機能するのでしょうか? […] アドレス ビットを切り捨てるのではなく、システムは 0:C0h の 5 バイトを 1000C0h にミラーリングします。実際、同じ手法は、
DOS=HIGH
で動作する DOS 5 以降でも使用されていました。その場合、DOS は、リニア アドレス 1000C0h に適切な遠方呼び出しが含まれるようにします。 […]
{{cite book}}:|work=無視されました (ヘルプ) (注: MSDOSTIP.TXT は MPDOSTIP.ZIP の一部であり、2001 年まで維持され、当時多くのサイトで配布されていました。提供されているリンクは、MSDOSTIP.TXT ファイルの HTML 変換された古いバージョンを指しています。)4DOS5TIP.TXT(注:提供されているリンクは、コレクションの一部であるHTML変換版のファイルへのリンクですMPDOSTIP.ZIP。)