Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

VB.NETで仮想CPUを作ろう (8) - SUB命令実装

VB.NETで学ぶ機械語の基礎 第8回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/09/23 14:00

本稿では、VB.NETを利用し、簡単な機械語で動く仮想CPUを作ることでバイナリプログラミングを満喫します。実際の業務で直接使えるケースは少ないと思いますが、デバッグやプログラミングの地力向上に役立つでしょう。 今回はSUB命令を実装する事によりCPUの理解を深めます。

目次

はじめに

 本記事はVB.NETの初歩的な記法だけを使って、簡単な機械語で動く仮想CPUの実装法を解説します(※CPUにもいろいろありますが、この記事ではIntel社が製造しているCPUを対象とします)。その過程を通じて、初心者でもバイナリプログラミングが楽しめることと、バイナリプログラミングの魅力を伝えたいと思っています。

 今回はSUB命令の実装を通じてCPUの理解を深めます。

これまでの連載

下準備

 今回は前回の実装を拡張していきますので、あらかじめ前回までの部分の実装を済ませておいてください。後は専門用語とCPU構造の確認のため、前回用意した3つのIntel社のマニュアルをすぐ読める状態にしてください。

 それに加えて、中巻 B: 命令セット・リファレンス N-ZのA-6とA-7ページを印刷しておくことをお勧めします。この表をあらかじめ印刷しておき、その紙を参照しながら実装作業をすると効率がよくなります。

前置き

  前回ADD命令の実装を行った際、テストしやすいように、テストドライバの下部に計算式が表示されるようにしました。しかし、このために、TestForm_Loadメソッド、CmdExeButton_Clickメソッド、RegisterValueChangedメソッドの、計3つものメソッドにまたがって実装を行いました。

 このように実装がいくつものメソッドに分かれると、コードの可読性を下げ、コードの保守性を下げる結果を招いてしまいます。コードの関連性が見えにくくなりますし、他のコードに混ざると論理的な一貫性がなくなり、人間には理解しにくいものとなるからです。

 まさしくリファクタリングを実施するべき状況といえます。

 そこで、SUB命令を実装する前にリファクタリングを実施します。実際の開発現場でも、この考えは有効で、元のコードに何らかの機能を付け加える際には、もっとプログラムを簡潔に表現できないか確認するとよいでしょう。

リファクタリングー分析

 リファクタリングする際は、何のコードを実装するのか改めて考え、その目的をなるべく簡単に一か所にまとめて実装できないかを検討します。今回の目的は、「計算式の結果を確認する」ことです。これを簡単かつ一か所で実装するために、それを阻害している要因を既存コードを分析して発見します。以下に実装部分を抜粋します。

フィールドの宣言
Private cpu As IntelCpu Private format As NumberFormatInfo Private before As Register
TestForm_Loadメソッド内
'レジスタの初期値を保存
EaxValueLabel.Tag = EaxValueLabel.Text
AlValueLabel.Tag = Me.before.ValueLowByte.ToString()
CmdExeButton_Clickメソッド内
'情報欄を更新する
Select Case CmdCombo.SelectedIndex
    Case CommandName.Mov
        If RegisterCombo.SelectedIndex = RegisterName.EAX Then
            ResultLabel.Text = "値が" & EaxValueLabel.Text & "に初期化されました。"
            EaxValueLabel.Tag = EaxValueLabel.Text
            AlValueLabel.Tag = Me.before.ValueLowByte.ToString()
        ElseIf RegisterCombo.SelectedIndex = RegisterName.AL Then
            ResultLabel.Text = "値が" & AlValueLabel.Text & "に初期化されました。"
            AlValueLabel.Tag = AlValueLabel.Text
        End If
    Case CommandName.Add
        If RegisterCombo.SelectedIndex = RegisterName.EAX Then
            ResultLabel.Text = EaxValueLabel.Tag.ToString() & _
                " + " & _
                UInteger.Parse(ValueText.Text).ToString("N", Me.format) & _
                " = " & EaxValueLabel.Text
            EaxValueLabel.Tag = EaxValueLabel.Text
            AlValueLabel.Tag = Me.before.ValueLowByte.ToString()
        ElseIf RegisterCombo.SelectedIndex = RegisterName.AL Then
            ResultLabel.Text = AlValueLabel.Tag.ToString() & _
                " + " & _
                UInteger.Parse(ValueText.Text).ToString() & _
                " = " & AlValueLabel.Text
            AlValueLabel.Tag = AlValueLabel.Text
        End If
End Select
RegisterValueChangedメソッド内
'レジスタの初期値を保存
EaxValueLabel.Tag = EaxValueLabel.Text
AlValueLabel.Tag = Me.before.ValueLowByte.ToString()

 このように実装を抜粋すると、コードが散らばっていることが一目瞭然です。この様な状況では、まずフィールドをみます。その理由は、フィールドやプロパティを使用しないと、メソッドをまたがって情報をやり取りできないからです。もちろん絶対にできないわけではありませんが、コードがこのように複数のメソッドに散らばっている場合はまず疑うべきです。

 フィールドをみると、beforeが一番今回の実装では影響が大きそうです。beforeは、「前方、~に先立って」などの意味を持つ単語ですから「変更前の数値」を保存していることが推測できます。

 試しにbeforeを検索するか、Microsoft Visual Studioなどの開発環境で作業している人は、beforeを選択して右クリックし、[すべての参照の検索]を選択して、このフィールドがどこで使われているか確認してください。TestForm_Loadメソッド、CmdExeButton_Clickメソッド、RegisterValueChangedメソッドの、3つのメソッドにまたがっていることが確認できます。

 これでbeforeが「変更前の数値」を保存していることが確認できましたので、その意味を考えてみます。そもそも、この情報はIntelCpuオブジェクトを利用するオブジェクトが持つべきものなのでしょうか? 設計思想は人それぞれですが筆者は違うと思います。それは、IntelCpuオブジェクトを利用するオブジェクトに負担を押し付けるということは、それだけコード量が増え、エラーが入り込む余地を与える結果に繋がるからです。

 今回はサンプルということもあり、テストドライバからしかIntelCpuオブジェクトは使用されていません。しかし、今後このオブジェクトを利用することを考えると、それらすべてのオブジェクトに余計な負担を強いることは賢明だとは思えません。そうするよりも、少し手間をかけてIntelCpuオブジェクトを使いやすく工夫する方が労力は減り、余計なエラーの発生を防げます。この考え方に基づき、「変更前の値」の情報はIntelCpuオブジェクトが持つことにしました。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • インドリ(インドリ)

    分析・設計・実装なんでもありのフリーエンジニア。 ブログ「無差別に技術をついばむ鳥(http://indori.blog32.fc2.com/)」の作者です。 アドバイザーをしたり、システム開発したり、情報処理技術を研究したりと色々しています。 座右の銘は温故知新で、新旧関係なく必要だと考えた...

バックナンバー

連載:VB.NETで学ぶ機械語の基礎

もっと読む

All contents copyright © 2005-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5