マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

最初の準備 #1

とりあえずRubyx86エミュレータを作ってみる。まず、以下のファイルを作る。

./emulator.rb
./vm/VM.rb
./vm/register/RegisterIndex.rb

まずRegisterIndex.rbから

module RegisterIndex
    EAX = 0
    ECX = 1
    EDX = 2
    EBX = 3
    ESP = 4
    EBP = 5
    ESI = 6
    EDI = 7
    
    EIP = 8
    
    ES = 9
    CS = 10
    SS = 11
    DS = 12
    FS = 13
    GS = 14
    
    RegisterCount = 15
end

これはレジスタの番号、EIP以降は適当に自分で決めた。セグメントレジスタにアクセスするときは基本的にindexを-9する

次にVM.rb

require "./vm/register/RegisterIndex.rb"

include RegisterIndex

class VM
    def initialize(memorySize)
        @registers = Array.new(RegisterCount);
        @memory = Array.new(memorySize);
    end
    
    def load(fileName)
        file = open(fileName)
        file.binmode()
        
        buf = file.read(512)
        count = buf.size < 512 ? buf.size - 1 : 511
        
        for i in 0..count
            @memory[0x7C00 + i] = buf[i]
        end
        
        file.close()
        @registers[EIP] = 0x7C00
    end
    
    def getCode()
        return @memory[@registers[EIP]].unpack("H*")[0].to_i(16)
    end
end

これは、コンストラクタでメモリとレジスタを初期化して、loadでファイル読み込んで0x7C00以降にファイルの内容を置くもの。getCodeでプログラムカウンタ(EIP)が指してるコードを取得する。現在はセグメントレジスタは使ってない。

最後にemulator.rb

#! ruby -Ks

require "./vm/VM.rb"

if ARGV.size == 0 then
    puts "ファイル名を指定してください"
    exit()
end

vm = VM.new(1 * 1024 * 1024)
vm.load(ARGV[0])
puts vm.getCode()

vmを初期化して引数に与えられたファイルを読み込み、最初の命令を取得して、そのコードを表示している。次回は何らかの命令を実行する予定