質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.80%

アセンブリ言語 プロテクトモード移行 CS,DS再設定 命令群先読みしてしまう問題について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,173

score 161

プロテクトモード移行するには思いつく限り(以下間違えて認識しているところがありましたら教えてください。)

・セグメントディスクリプタ(とりあえず1個でも作ればアクセスできるはず)
・IDT (これがないとソフトウエア割り込みを呼び出せない)
・IR0レジスタのPEビットを1にセットする。
・レジスタの値をセグメントベースからセレクタへ書き換える。(ここで先読みの問題が出てくる。)


この中の4つ目に関して不明点があるので教えてください。
今回の内容と非常に似た質問 ・・・ほぼ同じ
IR0のビットを1にセットした時点でメモリ空間へのアクセス方法
リアルモードでのセグメント方式のアクセス方法

セグメントベース × 10 + オフセット 


ではなく

セグメントセレクタ(ディスクリプタからベースアドレス参照) + オフセット


このアクセス方法に変化する。
つまり、CR0レジスタのPEビットを1にしたあとも
リアルモードで使っていたCS,DSの値をそのまま使っていると
おそらく対応セグメントディスクリプタが見つからずエラーになる。

なので、・・・
プロテクトモード用にCS,DSを再セットする。

MOV    CS, 0xXX    
MOV    DS, 0xXX        


このようにしてDS,CDともに再セットしたかったところだがCPUは命令を先読するため、
CR0レジスタのPEビットをONにした時点で
CPUはリアルモード値がセットされたCS,DSが使われた命令群をすでに読み込んでしまっていることになる。

ここから本題 どうやってそれを解消するのか

jmp $+2


この命令を使う。
このjmp命令を使うとCPUが先読みしていた命令群をクリアできる。

;/_/_/_/_/_/_/_/
;CR0レジスタPEオン
;/_/_/_/_/_/_/_/
mov eax, cr0
or eax, 0x00000001 
mov cr0, eax


;/_/_/_/_/_/_/_/
;先読みクリア
;/_/_/_/_/_/_/_/
jmp $+2

!ここから勘違いが発生してる可能性があります!
間違えてたらお願いします。

CR0レジスタのPEビットを1にした時点で
プロテクトモード用のアクセスに切り替わるが
その時点ですでにCPUに先に読み込まれていた命令群は
プロテクトモードではなくリアルモードで動くのですよね?
似た質問
なので

;/_/_/_/_/_/_/_/
;CR0レジスタPEオン
;/_/_/_/_/_/_/_/
mov eax, cr0
or eax, 0x00000001 
mov cr0, eax


;/_/_/_/_/_/_/_/
;先読みクリア
;/_/_/_/_/_/_/_/
jmp $+2
nop
nop

jmp [セレクタ:32bitオフセット]  ;←


リンク先の質問者さんは明示的に32bitで指定するための専用の命令が必要だといっておりますが
jmp $ + 2
で先読みをクリアしたあとならその命令というのは必要ありませんよね?

仮に、32bitオフセットができないとしても
mov cs,0xXX
でセレクタを指定することはできますよね?(命令が増えるけど)

0から作るOS
こちらでは
・先読みのクリア
・レジスタ再セット
をいっぺんにやっているように見えますが

  MOV    EAX, CR0        ; CR0レジスタの値を読み出します
    OR    EAX, 0x00000001        ; PEビットをOR命令でONします
    MOV    CR0, EAX        ; そのままCR0に書き込みます
    JMP    CODE_DESC:Pmode_start    ; CODE_DESCは0x08が入っています


このさいに32bitと認識されるための(?)専用命令を使っていますが
これはさきほどのように
CR0レジスタのPEビットを1にセットしたあとでも
その時点で先読みしていた命令群はリアルモード前提で実行され、16ビットレジスタを使えないから
という解釈であっていますか?

気になったのでお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

過去の質問の回答にもありますが、最後の

JMP CODE_DESC:Pmode_start


FAR JUMP が、

  • CS レジスタのロード(これによりプロテクトモード用のセグメントディスクリプタがロードされる)
  • 命令プリフェッチキューのクリア

を同時に行います。

同じ CS 内でのジャンプが NEAR JUMP、セグメントを異なる場所にするジャンプが FAR JUMP です。つまり FAR JUMP は CS レジスタのロードを伴います。
また、ジャンプすることで命令プリフェッチキューはクリアされる(それまで読んだのとは別の場所から処理が継続されるのですから、プリフェッチは全部捨てねば意味がありません)ので、上手くいくのです。

※32bit プレフィックスは不要です。必要なのは FAR JUMP です

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/27 17:52

    となると
    その次に動く命令は mov の次とはならない
    というのは
    csレジスタの値を変えてからフェッチされる命令という認識であっていますか?

    キャンセル

  • 2020/01/28 16:30 編集

    すみません なんでもないです理解できました。

    mov命令でcsレジスタを変更した後から
    フェッチした時点の命令は読みこむ場所が変わってきてしまう。
    さらにCPUによってフェッチの長さが違うから
    うまくそこをコントロールするのが難しい。

    jmp命令で先読みクリアとcsセットを同時に行えて一石二鳥というより
    そうする以外に方法がないのですね。
    (クリアとレジスタセットを同時に行わなければいけない。)

    キャンセル

  • 2020/02/06 18:15

    今更なのですが

    >※32bit プレフィックスは不要です。必要なのは FAR JUMP です
    プレフィックスを付けずにセグメント間ジャンプを使用したところシステムエラーが発生するので
    プレフィックスを付けずのセグメント間ジャンプはできませんでした。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • OSに関する質問
  • アセンブリ言語 プロテクトモード移行 CS,DS再設定 命令群先読みしてしまう問題について