インドリ「何、この思わせぶりなタイトルは?まぁいいか。じゃあ早速逆にレジスタにメモリデータを設定する場合を考えてみよう。」
インドリはまたしても
Intelマニュアル中のA-6・オペコードマップを見た。
インドリ「そんなこと言われても見るしかないピヨね。さくっと発見したよ。オペコードマップは同じ命令が同じ行にかたまっている場合が多いんだ。
じゃ〜ん。
行A・列1にあったピヨッ。
早速実装ダぁ〜ダァ〜だァ〜。エコー付けてみたよ。」
注目するべき部分だけ抜粋
public static OpeCodeInfo SearchOpeCode( byte value ) {
case 10:
switch ( col ) {
case 3:
info.Name = CommandName.MOV;
info.NextType =
NextInfoType.SourceVaryRegisterDestinationAddressing;
info.DestinationRegister = RegisterName.eAX;
info.SourceAddressMode = AddressingMode.O;
info.SourceOperand = OperandType.v;
break;
}
}
インドリ「この部分は毎度お馴染みだね。。次は命令解析部分だぁ〜、鳥ゃぁ〜」
注目するべき部分だけ抜粋
public void AnalyzeCommand( ) {
foreach ( byte data in datas ) {
OpeCodeInfo info = SearchOpeCode( data );
Command cmd = new Command( );
switch ( info.NextType ) {
case NextInfoType.SourceVaryRegisterDestinationAddressing:
//しまった!まだ実装していない。
cmd.DestinationRegister = GetRegister( info );
SearchModRM( ref cmd );
break;
}
cmds.Enqueue(cmd);
}
インドリ「んまり変わらないね。次はついに命令の実行だー。犯人はお前ダー。」
注目するべき部分だけ抜粋
public void ExecuteCommand( ) {
foreach ( Command cmd in cmds ) {
//途中省略
switch ( cmd.Name ) {
case CommandName.MOV:
Mov( cmd );
break;
}
}
}
注目するべき部分だけ抜粋
private void Mov( Command cmd ) {
switch ( cmd.NextType ) {
case NextInfoType.SourceVaryRegisterDestinationAddressing:
//CPUを持つPCのメモリにデータを送信。
ReceivesData(
cmd.SourceAddress,
cmd.DestinationValueLength,
cmd.DestinationValue );
break;
}
}
インドリ「次はCPUを保持するマシンオブジェクトの機能を実装するだけだ。」
public Machine( )
{
this.cpu = new ControlProcessingUnit( this );
this.memory = new byte[ 1024 ]; //ひとまずメモリを1K用意する
//データがCPUから送られてきた事が一目でわかる名前にする
this.cpu.SendDataEvent +=
new ControlProcessingUnit.MemoryAccessEventHandler
( ReceivesMemoryData );
//CPUがデータを要求していることが一目でわかる名前にする
this.cpu.ReceivesDataEvent +=
new ControlProcessingUnit.MemoryAccessEventHandler
( NotifyMemoryDataEvent );
}
後で解説
private void ReceivesMemoryData( object sender, MemoryAccessEventArgs e ) {
SetMemoryData( e.StartAddress, e.Value, e.DataLength );
}
注目するべき部分だけ抜粋
private void NotifyMemoryDataEvent( object sender,
ReceivesMemoryDataEventArgs e )
{
switch ( e.Target ) {
case RegisterName.EAX:
this.cpu.EAX = e.Value;
break;
}
}
インドリ「ピやったぁ。完成だピヨ。残りはSetMemoryとかを解説するだけだね。」
インドリィちゃん「私をだましたわねぇぇぇぇ。」
インドリ「えっそれどういう意味?」
(それより何よりもまずい!!!いつもよりも語尾が長い。こりゃかなり怒っているぞ。)
騙したとは一体何のことだろうか?次回へ続く。