あなたは、このようなコンピュータ等の理論やコンピュータ組成物の原則として、コースを研究している場合は、アセンブリ言語で、または、あなたはおそらくリアルモードとプロテクトモードの概念を聞いたことがあります。彼らは最後には、違いは何であり、どのように対処するためには何ですか?
最後に、王クールで、インテル製マイクロプロセッサーについての3つの動作モード「アセンブリ言語。」
インテル8086の発売に続き、インテルはリアルモード、保護モード、仮想8086モードで動作することができますランドマーク80386マイクロプロセッサを、開始した、それ以来、マイクロプロセッサは、今までは、3つの動作モードを提供します。次のようにマイクロプロセッサのインテルファミリーの3つのモードは次のとおりです。
- 実モード:作業モードは8086と同等です
- 保護モード:、マルチタスク作業環境のサポートを提供し保護メカニズム
- 仮想8086モード:ユーザーが保護されたモード8086で1つまたは複数のプログラムを実行するために、このように提供された1種類の操作8086のモードにプロテクトモードから切り替えることができると便利です
私たちのシステムブートは、CPUが最初のリアルモードでいくつかの作業を完了した後、保護モードに飛び込んだとき、私たちのシステムのためのマルチタスク環境のサポートを提供します。私たちは保護モードをシステム上でリアルモードでプログラムを実行する必要があります(DOSシステムで使用されるアセンブリを学習するとき、たとえば、)と、我々は仮想8086で、現在の保護モードで「偽」リアルモードを取得する必要がある場合モード。
GDTと記述子
リアルモード(8086の上に作業するときに理解されるように)、我々は、16ビット・レジスタ、16ビットデータバス、アドレスバス20、アドレス指定可能範囲ビット1Mを提供する、16ビットのCPUです。物理アドレスは、次の式を、次のとおりです。
\ [物理セグメントアドレスaddress =オフセットアドレス+ 16 * \]
前記セグメントアドレスとオフセットアドレスは16ビットです。
最初から80386、32ビット時代の家族へのインテルのCPU、この時CPUは32ビットアドレスバス、4Gのアドレス指定可能な範囲を持っています。CPUは、32ビット・レジスタ、アドレス可能空間4GBの1つのレジスタを有します。
リアルモードでは、我々が使用するセグメントアドレス:オフセットアドレス我々は唯一の16個のレジスタを持っているので、アドレス指定、範囲を扱う単一レジスタが1メガバイトに達していないが、今、私たちは、32ビット・レジスタ、単一レジスタを持っていますアドレス指定可能な範囲は、最大4GB持って、あなたは必要としないセグメントレジスタではないでしょうか?答えはノーです。「:オフセットセグメントアドレス」を表現するための方法が、プロテクトモードでは、アドレスはまだコンセプトのセグメントは、根本的な変化を遂げています。
リアルモードで、セグメント値(セグメントアドレスの値)またはアドレスの一部。保護モードでは、まだ元ながらセグメントの値が16で、CSである、DS等、レジスタであるが、今回は彼らが唯一のインデックスは、インデックスされたエントリのデータ構造を指し、詳細Aに定義された入力部住所、境界、プロパティというように、このデータ構造を開始する、と呼ばれるGDT、と呼ばれる、GDT内の各エントリを(おそらくLDT、我々は最初の大部分を議論し、実際に)記述子
プロセスへの対応
私たちは、ビュー内の保護されたアドレッシングモードの過程を見てください。これに先立ち、注意すべき点がいくつかあります。
- GDTは、メモリに格納されるデータ構造であるので、記述子のシリーズに設定されている開始アドレスを有するべきです
- 登録GDTR、GDTRを48であり、我々は、このレジスタの後半で議論 - GDTは、保存するために、専用のレジスタでアドレスを開始します
- GDT各記述子は、セグメント、開始アドレス(ベースアドレス)を含むセグメントなどの特性を記述する
- これは、32ビット、オフセット実モードと保護モードと同じです
さて、ここでのマップがあり、我々は対処され、再びどのように保護モードを介して、このチャートを見ることができます。
- アドレス指定の場合は、まず、登録GDTのベースアドレスを導き出すGDTR見つけます
- GDTのベースアドレスと、セグメント・レジスタインデックスにが格納されるエントリセグメントは「参照」を登録することを求め、ディスクリプタの両方を参照することができます
- 記述子、得られたセグメント記述子のアドレスを出発して得ることができるから記述子であります
- セグメントの開始アドレスと、オフセットアドレスが引き継ぐを加え、最終的な与えることができるであろう線形アドレス
- リニア・アドレス(仮想アドレス)と、変換、対応する物理アドレスを取得します
私はここで、あなたはすでに手続きを扱うの大まかなアイデアを持っていると信じている、と我々は我々が上記で詳細に言及していないものを見て
GDTRレジスタ
GDTRは、ベースアドレスを保持する48ビットのレジスタであり、GDT(GDT又は長さ)、GDTのベースアドレスの上位32ビット、下位16ビットの上限を制限します。16ビットやるされている、彼らは境界が対応する、ああしているGDTRプロテクトモードのセグメントレジスタを覚えておいてください。
記述子
以下の構造を有するGDT 8バイトの各記述子
私たちは、セグメントベースアドレスとセグメント境界を確認するために、これらの性質を制御することはできません。まだ連絡アドレッシングの上ではありません。
あなたは、セグメントのベースアドレスとセグメント境界が一緒に分離されていませんが、何を聞いて、求めることができますか?これは主に歴史問題で、我々が検討しません。
コード
ただ、すべての水の後に理論を見て、私たちは実際に味わうコードのシンプルな作品を参照してください。
[SECTION .gdt]
; GDT
; 段基址, 段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
; GDT 结束
GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限
dd 0 ; GDT基地址
; GDT 选择子
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
上記のコードは、我々はさらに、先ほど定義したので、我々が使用する最初の三つLABLE_xxxは、値が必ずしも正しくない特徴、マクロ記述は3つのセレクタを画定呼ばれる前記コーナー.gdtセグメントを定義しますこれは、初期化されませんでした。記述子の役割はセグメントベースアドレス、セグメントの範囲と記事の最後に定義されている対応する選択位置、サブ属性であり、興味が見ることができます。
GdtPtr
GDTRとは、同一のコンテンツに入れていませんか?我々はリアルタイムで保護されたモードに入る前に、はい、私たちは、レジスタGDTRにロードされたGdtPtr値に必要な次のコマンドを使用してlgdt [GdtPtr]
それは何だった最後の二つのGDTセレクタのですか?GDTディスクリプタベースアドレスとオフセットしているように見える、図に示すように、少し複雑であり、すべての権利はありません。
TIは、RPLおよび選択サブ属性であり、残りの高い13は、ディスクリプタテーブルの位置、すなわち、GDTにディスクリプタを示すいくつかの記述子
最後に、我々は彼らの上に使用する方法を見て
[SECTION .s32]; 32 位代码段.
[BITS 32]
LABEL_SEG_CODE32:
mov ax, SelectorVideo
mov gs, ax ; 视频段选择子(目的)
mov edi, (80 * 11 + 79) * 2 ; 屏幕第 11 行, 第 79 列。
mov ah, 0Ch ; 0000: 黑底 1100: 红字
mov al, 'P'
mov [gs:edi], ax
; 到此停止
jmp $
SegCode32Len equ $ - LABEL_SEG_CODE32
上述代码将一个字母P显示在屏幕上。gs中保存的是显存的选择子,edi为偏移地址,然后使用mov [gs:edi], ax
将ax的内容写入到地址为gs所指的描述符中的段基址+edi的内存处,由于这里写入的是显存,所以将会将一个字母P显示在屏幕上。
Descriptor宏的定义如下
; usage: Descriptor Base, Limit, Attr
; Base: dd
; Limit: dd (low 20 bits available)
; Attr: dw (lower 4 bits of higher byte are always 0)
%macro Descriptor 3
dw %2 & 0FFFFh ; 段界限1
dw %1 & 0FFFFh ; 段基址1
db (%1 >> 16) & 0FFh ; 段基址2
dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性1 + 段界限2 + 属性2
db (%1 >> 24) & 0FFh ; 段基址3
%endmacro ; 共 8 字节
完
参考:
- 《汇编语言》 王爽
- 《一个操作系统的实现》 于渊