7

さまざまな時期に、私は両方を使用しました

int 0x20

mov ah, 0x4c
int 0x21

16ビットアセンブリプログラムを終了する方法として。

しかし、2つの違いは何ですか?


編集:皆さんのコメントをありがとう。AlexeyによるPSP(プログラムセグメントプレフィックス)への参照をフォローアップし、MicrosoftMASMサポートからこのナゲットを生成しました。

この記事は、単なるリターンコード以上の違いがあることを示唆しているようです。

2つをもう少し明確に結び付けることができる人に受け入れられた答えを授与することを嬉しく思います。

4

3 に答える 3

17

まず、いくつかの背景。DOS は、システム コールに割り込み 21h を使用します。AH は、INT 21h が提供するさまざまな機能を逆多重化するために使用されます。プログラムが実行されると、DOS はプロセスに関する情報を含む PSP (プログラム セグメント プレフィックス) として知られる 256 バイトをその前に置きます。

DOS の元の終了関数はINT 21/AH=00. 現在、どうやら DOS 開発者は、プログラムから戻ることがプログラムを終了する方法であるべきだと判断したようです (これは CP/M から来たのですか?)。RET(near) スタックから単語をポップし、それにジャンプします。したがって、プログラムが作成されると、そのスタックは word で始まります0000。PSPの始まりです。そのため、PSP の開始時に、プログラムを終了するコードがあります。そのコードを小さく保つために、INT 20hは へのエイリアスとして機能しMOV AH,00h ; INT 21hます。

[編集: これは下のスクリーンショットで見ることができます。]

DOS 2.0 は、リターン コードを含め、Unix から多くのものを取り入れました。そこで、INT 21h/AH=4chリターンコードをOSに返す新しいINT 21h関数が登場しました。この関数は、複数のセグメントを持つことができる EXE ファイル (AFAIR も DOS 2.0 の新機能) で動作するようにも設計されています。以前の終了関数 (INT 20h および INT 21h/00) は、CS が COM プログラムでのプログラム起動時と同じである、つまり、プログラムの 256 バイト前の PSP を指していると想定しています。

[編集:<code>debug</code> を使用した DOS プログラム構造の図

歴史的なメモ: CP/M では、プログラムを終了する方法が 3 つあります。

  • BDOS 機能 0 の呼び出し (INT 21 AH=00h、DOS 機能 0 に相当)
  • 0000h の WBOOTF ロケーションにジャンプ (PSP オフセット 000h に相当)
  • 戻る

WBOOTF の場所は 3 バイトで構成されていました。1 バイトはジャンプ用、2 バイトはジャンプ先 (BDOS の WBOOT 機能) です。

CP/M の初期のバージョンでは、BDOS 関数 0 を呼び出すか、WBOOT にジャンプすると、CP/M の一部がディスクから再ロードされ (ウォーム ブート)、続いて一部の OS 初期化が実行されました。一方、RETurning は CCP (コンソール コマンド プロセッサ、COMMAND.COM に相当) に直接戻り、次のコマンド ラインを要求します。AFAIU、CP/M 3 は通常 ROM にロードされ、WBOOT の場所に戻るため、ROM から OS の一部が再ロードされます。

于 2012-09-26T01:22:58.287 に答える
7

後者の int 0x21 では、リターン コードを指定できます。

戻りコードは、レジスター AL に入れられます。

http://spike.scu.edu.au/~barry/interrupts.html#ah4c

于 2012-09-25T22:00:35.637 に答える
2

これは私が知っていることです。

MOV AH, 0x4C
INT 0x21

実行中の EXE ファイルを終了します。コードセグメントは CS を登録するため、EXE ファイルはこの方法で終了する必要があります。間違っていたら訂正してください。ただし、この方法で COM ファイルを終了すると、予期しない結果 (クラッシュ、ハング、再起動など) が発生します。したがって

INT 0x20

COM ファイルを終了します。

CS は、COM プログラムのプログラム起動時と同じです。つまり、プログラムの 256 バイト前の PSP を指します。(CodeSegment InstructionPointer CS:IP、CS にはコードセグメントが含まれます)。はい、私たちはレジスターについて話しています。変数は食器棚のようなものです。引き出しに何かを正しく入れることができるように機能します。AX=0000 BX=0000 CX=0000 (CXはCLとCHで構成) など

COMフ​​ァイルは一般的に常に64Kに制限されていると思いました。私が考えた 2 番目の理由は、COM ファイルにはデータ セグメントがなく、データはありますが、コードと同じセグメントにあるということです。コード以外のセグメントはないと思いました.COMファイルのすべてのデータは64K内に保存されています。EXE ファイルにはセグメントがありますが、一部の EXE ファイルは、正しいメモリ モデルを使用すると、より多くのセグメント (CS:IP) を持つことができます (Intel メモリ モデルを参照)。

  • 小さい* CS=DS=SS
  • 小さな DS=SS
  • Medium DS=SS、複数のコード セグメント
  • コンパクトな単一のコード セグメント、複数のデータ セグメント
  • 大規模な複数のコードおよびデータ セグメント
  • 巨大な複数のコードおよびデータ セグメント。1 つのアレイが 64 KB を超える場合があります

EXE ファイルには、メモリ モデル SMALL を使用した場合、64K の制限があります。より大きなメモリ モデルと 32 ビット ポインターを使用する場合は、64K を超えるアドレスを指定できます (まだ制限があります)。それが「コツ」だと思いました。

今では、なぜ EXE ファイルを使用する必要があるのか​​、誰もが私に不平を言っています。以上が理由です。メモリモデルはウィキペディアから来ています。気にしない人のために、私はこれを専門家から難しい方法で学びました. ピーター・ノートンとジョン・ソーチャ。Norton Utilities から (The Norton Commander for DOS の背後にいる人物)。彼は、「IBM-PC のアセンブリ」のようなアセンブリに関する本を持っていました。あなたはそれを読むべきです、彼はそれを最もよく説明しています. 彼は私にとって良い先生のようでした。Microsoft CodeView は、私に多くのことを明らかにしてくれました。DOS C でプログラミング?Turbo C 2.0 は最高です。ああ、もうプログラミングはしません。

于 2015-12-22T22:55:19.167 に答える