SearchOpeCodeMapメソッドの変更点
まずはCommandName
列挙体にADD命令を加え、その後SearchOpeCodeMap
メソッドを変更します。
SearchOpeCodeMap
メソッド内でADD命令に関する処理を付け加える場所は、コメントの「行と列から命令を割り出す」の真下、MOV命令を判別していく箇所近辺です。分かりやすいよう、前回のSearchOpeCodeMap
メソッドにコメントを追加して掲載します。
'オペコードマップを検索し、実行する命令と対象となるレジスタを探索する。 Private Shared Function SearchOpeCodeMap(ByVal binary As Byte) As OpeCode Dim result As OpeCode = New OpeCode() '指定されている命令を特定するために行と列を導出 Dim row As Byte = CByte((binary And &HF0) >> 4) Dim col As Byte = CByte(binary And &HF) '行と列から命令を割り出す 'ここにADD命令に関する処理を追加 Select Case row 'この辺にADD命令に関するプログラムを加える Case 11 'MOV命令についてのプログラムは省略 Case Else Throw New ArgumentException("行" & row & "列" & col & "には対応しておりません。") End Select '結果を返す Return result End Function
ここにどんなプログラムを追加すると良いでしょうか? 皆様も一度考えてみくてください。ヒントは『IA-32 インテル アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル、中巻 B: 命令セット・リファレンス N-Z』のA-6とA-7ページです。
自分で一度この表からADD命令を探してみてください。そして、その動作をプログラムで行わせるにはどうしたらいいのか考えてみてください。ただし、今回は1つ条件があります。それは「AL, lvとeAX, lv」だけを探してください。理由はメモリを実装していないからです。準備の不足により、lv以外の条件のADD命令はまだ実装出来ません。
前回のMOV命令の実装を参考に、実装を試みてください。
実装できましたか? 筆者の回答例を提示します。答え合わせをしてください。
'行と列から命令を割り出す Select Case row Case 0 Select Case col Case 4 result.Name = CommandName.Add result.Destination = RegisterName.AL result.BitCount = 8 Case 5 result.Name = CommandName.Add result.Destination = RegisterName.EAX result.BitCount = 32 End Select
特に難しいところはないと思います。もし分からない場合は前回の「SearchOpeCodeMapメソッドの変更点」を読んでください。
これで、IntelCpuがADD命令を探せるようになりました。
次は、SearchOpeCodeMap
メソッドの逆の処理をするGetBinary
メソッドに、ADD命令に関するプログラムを追加します。
GetBinaryメソッドの変更
このメソッドの変更も簡単です。変更した部分が分かるように掲載します。
'オペコードマップを検索し、実行する命令と対象となるレジスタを探索する。 Private Shared Function SearchOpeCodeMap(ByVal binary As Byte) As OpeCode Dim result As OpeCode = New OpeCode() '指定されている命令を特定するために行と列を導出 Dim row As Byte = CByte((binary And &HF0) >> 4) Dim col As Byte = CByte(binary And &HF) '行と列から命令を割り出す Select Case row Case 0 Select Case col Case 4 result.Name = CommandName.Add result.Destination = RegisterName.AL result.BitCount = 8 Case 5 result.Name = CommandName.Add result.Destination = RegisterName.EAX result.BitCount = 32 Case Else Throw New ArgumentException("命令" & cmd.ToString() & "は" & _ reg.ToString() & "レジスタをサポートしておりません。") End Select Case 11 '長いので省略 Case Else Throw New ArgumentException("行" & row & "列" & col & "には対応しておりません。") End Select '結果を返す Return result End Function
これで、IntelCpuオブジェクトに対してADD命令の実行を行いやすくなりました。
次は、実行部分であるExecuteCommand
メソッドにプログラムを追加します。
ExecuteCommandメソッドの変更点
この部分は大変簡単です。特に説明はいらないと思いますので、実装だけ掲載します。
'解析済みの命令を実行します。 Public Sub ExecuteCommand() Dim cmd As OpeCode While cmds.Count <> 0 cmd = cmds.Dequeue() Select Case cmd.Name '命令を選択して実行 Case CommandName.Add 'このプログラムを追加 Add(cmd) 'このプログラムを追加 Case CommandName.Mov Mov(cmd) End Select End While End Sub
次のページでは、ADD命令について説明します。