CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

GCCプログラミング(3)

djgppで生成されるコードが変・・なんて云っていましたが
結論から言うと、このコードは80386のプロテクトモード上で動作するっていうことです。

本来、DOSコマンドプロンプト上で実行させる場合は初期化ルーチンでプロテクトモードに切替え、
DOSエクステンダのサービスを使って動作するわけで、今回、何のOSも載っていないCPUボードで
リアルモードからいきなりコードを実行しようとしてもダメなわけです。

では何をすればいいのか、ですが先ず考えられるのが
(1)リアルモードからプロテクトモードに切替える
(2)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されるのでアドレス不一致問題も解消されます


さて今までリアルモードで単に高速の8086として扱っていた386をプロテクトモードに切替えて
本来のパワーを発揮させたいのですが、CPUそのものの制御というのはOSの設計でもしようなんて
時くらいで普通はやりません。
参考にできる資料も少ないですが自分の持っている中ではこの本がズバリ書いてあり助かりました

イメージ 1