SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

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

VB.NETで仮想CPUを作ろう (5) - CPUの基礎動作の実装

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

ConvertValuesメソッドの解説

 機械語は1バイトごとに読み込みます。ですから、ダブルワード(32ビット)の値を得るには4回読み取った後、リトルエンディアン方式に基づいてそれらを逆にし、最後に「4個の1バイトのビット列」を「32ビットの1つの値」へ変換しなければなりません。その最後の処理を実装しているのがConvertValuesメソッドです。ConvertValuesメソッドの実装は次のとおりです。

'バイト列をダブルワードの値へ変換します
Private Function ConvertValues(ByVal values() As Byte) As Integer
    Dim result As UInteger = (CUInt(values(0)) << 24)
    result += (CUInt(values(1)) << 16)
    result += (CUInt(values(2)) << 8)
    result += values(3)
    Return result
End Function

 このメソッドのポイントは「算術左シフト」と「型変換」です。

 算術左シフトとは、2進数表記でビットを左へずらし、開いた右の部分を0で埋める算術のことです(※厳密には他の方式もありますが、本稿ではこの形式だけを使います)。

 始めて聞く人も多いと思いますので例を挙げます。

 例えば、2を2進数で表記すると、2ごとに桁上がりするので「10」です。それを左にずらすということは「100」になります。100ということは10進数に直すと「2 * 2 = 4」です。このように、算術左シフトをすると値は2倍になります。

算術左シフトをすると値は2倍に
2進数の  10 …… 10進数で       2x1 + 1x0 = 2
2進数の 100 …… 10進数で 4x1 + 2x0 + 1x0 = 4

 ではなぜ算術左シフトをしなくてはならないかと言うと、1バイトの値をそのまま足しても元の数に戻らないからです。これもイメージが沸きにくいので例を挙げて説明します。

 例えば、8280(16進表記で2058)は、「20」(10進で32)と「58」(10進で88)に分解されてCPUオブジェクトに送られてきます。これをそのまま足してしまうと78(16進)となってしまい120(10進)となってしまいます。ですから、まず20を8ビット左算術演算して8192(32*2の8乗)にしてから、最後の88を足すのです。これでもとの値8280に復元できます。

 型変換をする理由はビット数を合わせるためです。1バイト配列の変数valuesはそのまま算術左シフトしてもVBが8ビットしかないと思っているので切り捨てられます。だから32ビットであることを明示しなくてはならないのです。

 バイナリプログラミングではシフト演算と桁を合わせることが大変重要です。これを覚えておけば一般の業務でも役に立ちますのでしっかりマスターしましょう。

 これでAnalyzeBinaryメソッドの主な処理の解説が終わりました。これらの解説を踏まえて、もう一度AnalyzeBinaryメソッドを確認してみてください。初心者の方もきっと理解できるはずです。その際、Windows付属の関数電卓を使用していろいろな値を計算してみると理解が進むと思います。

命令の実行

 いよいよ機械語の命令を実行する部分へたどり着きました。このCPUの動作はExecuteCommandメソッドで実装されています。

'解析済みの命令を実行します。
Public Sub ExecuteCommand()
    Dim cmd As OpeCode
    For Each cmd In cmds
        Select Case cmd.Name
            '命令を選択して実行
        End Select
    Next
End Sub

 とても簡単です。解析されて処理待ちになっている命令に対応するメソッドを実行するだけです。今は何の命令も実装されていませんが、次回から具体的な命令を実装していきます。

 次に、残りのOpeCode構造体を解説します。

OpeCode構造体

 OpeCode構造体は次のように定義しています。

Public Structure OpeCode
    Private m_cmd As CommandName
    Public Property Name() As CommandName
        Get
            Return Me.m_cmd
        End Get
        Set(ByVal value As CommandName)
            Me.m_cmd = value
        End Set
    End Property

    Private m_reg As RegisterName
    Public Property Destination() As RegisterName
        Get
            Return Me.m_reg
        End Get
        Set(ByVal value As RegisterName)
            Me.m_reg = value
        End Set
    End Property

    '現在どのビット数の値を扱っているのかわかった方が便利
    Private m_bit As Byte
    Public Property BitCount() As Byte
        Get
            Return m_bit
        End Get
        Set(ByVal value As Byte)
            m_bit = value
        End Set
    End Property

    '8ビットの場合、上位アドレスなのかの情報がいる
    Private m_hi As Boolean
    Public Property IsHi()
        Get
            Return Me.m_hi
        End Get
        Set(ByVal value)
            Me.m_hi = True
        End Set
    End Property

    Private m_val As Register
    Public Property Value() As Register
        Get
            Return Me.m_val
        End Get
        Set(ByVal value As Register)
            Me.m_val = value
        End Set
    End Property
End Structure

 今回はまだ命令を実装する段階ではないので必要最低限のものだけを用意しました。気づいた方もいると思いますが、この構造体はRegisterValueChangedEventArgsクラスとほぼ同じです。ですからこの構造体の内容に関しては、『VB.NETで仮想CPUを作ろう (4) - テストドライバの改良』のRegisterValueChangedEventArgsクラスの説明を参照してください。

 これでCPUの基本動作は実装しましたが、そのままでは非常にIntelCpuクラスが扱いにくいので、いくつかの便利なメソッドを追加します。

次のページ
GetBinaryメソッドの実装

この記事は参考になりましたか?

VB.NETで学ぶ機械語の基礎連載記事一覧

もっと読む

この記事の著者

インドリ(インドリ)

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

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2840 2010/04/27 12:01

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー