2011-08-02 15 views
5

いくつかのシンプルなソースコードを勉強するときに、単純なアセンブリの問題について混乱します。このウェブサイトで32ビットレジスタ/命令をリアルモードで使用できますか?

http://wiki.osdev.org/Babystep7次のコードは、私がプロテクトモードにリアルモードから切り替える方法を知っているプロテクトモードにリアルモードから

mov eax, cr0 
or al,1 
mov cr0, eax 

を切り替えることです。
しかし、私の質問は、プログラムがまだリアルモードになっているからです。どのようにして32ビットのレジスタや命令を使用できますか?

リアルモードで32ビットのレジスタ/命令を使用できますか?

+1

プリフェッチャをクリアする必要があると思います(通常はjmpを使って次のメモリ位置に移動する必要があります)。 –

答えて

4

プロセッサがリアルモード(ブート直後)で動作する場合、プロセッサはデフォルトで16ビットコードになります。ただし、ではなく、は32ビット命令を使用できないことを意味します。

単一命令のデフォルトモードを変更する「オペランドサイズオーバーライド」接頭辞(66h)があります。この接頭辞が16ビットリアルモードで実行される命令で使用される場合、命令は32ビットに切り替えられます。逆に、この接頭辞が32ビット保護モードで実行された命令で使用されると、命令は16ビットに切り替わります。

このプレフィックスを使用すると、32ビットのレジスタを16ビットのリアルモードで使用できます(このプレフィクスは67hでアドレスサイズをオーバーライドします)。 16ビットコードをアセンブルするときに、命令で32ビットオペランドを使用しようとすると、アセンブラは自動的にこの接頭辞を自動的に生成します。

残念ながら、64ビット命令にはこのようなオーバーライドプレフィックスはないため、リアルモードでは使用できません。これらを可能にするには、「ロングモード」に切り替える必要があります。

+0

ありがとう、これは私の問題を解決します – mike820324

+0

リアルモードでも64ビットレジスタを使用できますか? –

4

私が理解する限り、リアルモードはCPUで実行できるコマンドには影響しませんが、CPUメモリ参照コマンドの解釈方法に影響します。

はい、eaxを使用できますが、[eax]メモリセルを取得することはできません。

Intel's Manualの関連部分を参照してください。

+0

私は "...しかし、あなたは[eax]メモリセルを手に入れることができません"と信じています。真実ではない。私の理解では、リアルモードでは、eaxの値が0x0000FFFF以下であれば、[eax]は完全に有効なアクセスです。 [eax]にアクセスしようとすると、eaxの値が大きくなると保護違反が生成されます(ただし、[eax]の場合は保護違反を生成する必要はありません)。 – Orby

0

私が知る限り、リアルモードでは、32ビットレジスタは使用できません。 32ビット制御レジスタCR0では、リアルモードと保護モードはCR0(PE)の最初のビットを調べることによって決定されます。このコードでは、最後の行(mov cr0、eax)のPEを変更します。 この行の後では、32ビットレジスタ参照をもう使用できないと思います。

+1

これは正しくありません.16ビット/リアルモードで32ビットレジスタにアクセスするには、0x66接頭辞を使用できます。 –

0

単純なアドレッシングでは、オペランドと命令サイズの接頭辞がうまく機能しました。 Windows(3.1以降で9x)用に書いた、16ビットの保護された(初期には実際の)モードアプリケーションは、WindowsメモリAPIを使用して64Kを超えるメモリ領域を割り当てることができました。いずれにしても(遠くの)ポインタサンクを使用し、私のアプリに言及されたプレフィックスは、16ビットモードで実行されていても40MBの領域を十分に活用しました。

同様のことを試してみると、命令サイズの接頭辞が16ビットと互換性のない32ビット命令セットを有効にすることに注意してください。 16ビットは通常、セグメント演算をしていない限り、実際のモードであるかプロテクトモードであるかは気にしません。だから、あなたのコンパイラはおそらく血まみれの殺人を叫ぶことなくそれらを生成しないので、emitを使って32ビット演算をコードに渡す必要があります(少なくとも私はしました)。

0

32ビットリアルモードがあり、unreal modeと呼ばれます。その時代には、セレクタと保護されたモードオーバーヘッド全体を使用することなく、アドレス空間全体にアクセスするために使用されました。

0

おそらく、LoadAll オペコード0F07hを使用して、16ビットリアルモードで32ビットアクセスを与えることができます。

+0

このオペコードはほとんど文書化されておらず、ほとんどの現代のCPUでは、そのエンコーディングのセマンティクスが命令 'sysret'に取って代わりました。 – minmaxavg

関連する問題