2017-04-12 15 views
4

通常、プログラマはレジスタ(と時にはセグメント)をブートローダの最初の行にフィックスアップしているのが普通です。例えば:BIOSはブート手順の間に、すべてのレジスタをクリアします:起動時のデフォルトのレジスタとセグメントの値x86マシン

inc cx 
dec bx 
inc bp 
dec di 
xor ax, ax 

私は私が知っていることであるということだろう。

ブートローダーのレジスタとセグメントを初期化するのは良い習慣ですか?はいの場合、デフォルトのレジスタ、セグメント、ポインタの値は何ですか(おそらくチップセットに依存します)?

+2

インテルのマニュアルでは、CPUの電源投入時に各レジスタに含まれる値を指定しています。しかし、あなたはBIOSがブートローダに手を差し伸べた後の状態を尋ねているので、誰が知っているのですか? – Nayuki

+0

ありがとう@Nayuki。あなたが正しいです。 –

+6

ブートローダを実行するときには、約1つのことしか想定できません(1980年代の一部の例外を除いて互換性のないコンピュータは例外です)。つまり、BIOSによってブートされたドライブ番号は、_DL_レジスタ内にあり、フラグの状態、セグメントレジスタの状態、汎用レジスタの状態については何も仮定しないでください。 –

答えて

3

セグメント・レジスタの設定について言及しているので、コードは16ビット・コードのように見えますので、私はあなたが(EFI/UEFIではなく)従来のIBM-PCブートローダ(PC-BIOS)について議論していると仮定します。レガシーのブートローダでは、製造された大半の機器のために、あなたが想定できるものはほとんどありません。

PC-BIOSがブートセクタを使用可能なブートデバイスからロードして制御を転送するまでに、すべてのレジスタの状態は使用可能な値になります。 80年代と90年代のいくつかの非標準(および100%互換性のないBIOS)を除いて、レジスタDLには、BIOSの起動元のブートドライブ番号が含まれています。この値はInt 13h disk service routinesを呼び出すために使用された値です。

SS:SPは、RAMのどこかを指している可能性がありますが、BIOSとBIOSで異なる点があります。特にメモリにデータをロードする場合は、スタックポインタ(SSSP)を設定する必要があります。自分で特別に設定しない限り、意図せずにスタックにデータを上書きすることができます。 IPは常に0x0000に設定されています:0x7c00(CS = 0000、IP = 0x7c00)コントロールが(通常FAR JMP経由)ブートローダに転送されたときに

一部はCSと主張しています。残念ながら、これは保証されていません。いくつかのブートローダーは、物理アドレス0x07c00(0x07c0 < < 4 + 0x0000)も指す0x07c0:0x0000を使用することが知られています。これは異なるsegment:offset addressingが同じ物理アドレス(0x07c00など)を表すことができるためです。私は、と書いて、と仮定して、CSが常に0x0000であると仮定すると、環境によっていくつかの面白いバグが発生する可能性があります。

文字列命令(CMPSおよびMOVSなど)に使用される方向フラグ(FLAGSレジスタのDF)は、特定の方向であると見なすべきではありません。ほとんどのコードでは前方移動(DF = 0)が使用されますが、BIOSがブートローダーにジャンプする前にBIOSが設定した方向であるという保証はありません。そのため、前方移動の場合はCLDで明示的にクリアするか、後方移動の場合はSTDと設定する必要があります。

上記のDLのほかに、汎用レジスタがまったく初期化されていないと仮定するべきではありません。多くの場合、ブートローダーはゼロであると見なします。これはほとんど決してありません。

これらの多くのことが、私のStackoverflow General Bootloader Tipsで議論されています。

+1

大変ありがとうございます。ちなみに、私はタグにBIOSを追加しました。 –

関連する問題