本来、DOSのコマンドプロンプト上で実行させる場合は初期化ルーチンでプロテクトモードに切替え、
DOSエクステンダのサービスを使って動作するわけで、今回、何のOSも載っていないCPUボードで
リアルモードからいきなりコードを実行しようとしてもダメなわけです。
DOSエクステンダのサービスを使って動作するわけで、今回、何のOSも載っていないCPUボードで
リアルモードからいきなりコードを実行しようとしてもダメなわけです。
では何をすればいいのか、ですが先ず考えられるのが
(1)リアルモードからプロテクトモードに切替える
(2)32ビットセグメントを使用する
ということです
(1)リアルモードからプロテクトモードに切替える
(2)32ビットセグメントを使用する
ということです
このことによって
・相対コール命令のディスプレースメントが4バイト相対になる
・レジスタを操作する各命令がプリフィックスなしで(同じオペコードで)32ビットレジスタを制御
ができるようになります
たとえば前回生成されたコードを32ビットセグメント環境下で見直すと
・相対コール命令のディスプレースメントが4バイト相対になる
・レジスタを操作する各命令がプリフィックスなしで(同じオペコードで)32ビットレジスタを制御
ができるようになります
たとえば前回生成されたコードを32ビットセグメント環境下で見直すと
-u2000 _start: 0000:2000 E817000000 CALL 0000201C ←32ビット相対コール 0000:2005 F4 HLT _end: _main: 0000:201C 55 PUSH EBP ←32ビットレジスタ命令 0000:201D 89E5 MOV EBP,ESP ←32ビットレジスタ命令 0000:201F 90 NOP L4: 0000:2020 6808200000 PUSH 00002008 ←32ビット実アドレス 0000:2025 E84A040000 CALL 00002474 ←32ビット相対コール 0000:202A 83C404 ADD ESP,+04 ←32ビットレジスタ命令 0000:202D EBF1 JMP 2020 0000:202F 90 NOP
となって、同じバイナリにもかかわらず生成したいコードそのものになっているのがわかります
CALL命令の後の謎の「0000」が実は32ビットアドレスの上位であり、この2バイトがCALL命令に含まれるため
飛び先アドレスも+2されるのでアドレス不一致問題も解消されます
CALL命令の後の謎の「0000」が実は32ビットアドレスの上位であり、この2バイトがCALL命令に含まれるため
飛び先アドレスも+2されるのでアドレス不一致問題も解消されます
さて今までリアルモードで単に高速の8086として扱っていた386をプロテクトモードに切替えて
本来のパワーを発揮させたいのですが、CPUそのものの制御というのはOSの設計でもしようなんて
時くらいで普通はやりません。
参考にできる資料も少ないですが自分の持っている中ではこの本がズバリ書いてあり助かりました
本来のパワーを発揮させたいのですが、CPUそのものの制御というのはOSの設計でもしようなんて
時くらいで普通はやりません。
参考にできる資料も少ないですが自分の持っている中ではこの本がズバリ書いてあり助かりました