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

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

ジャンプ命令追加 #8

今回はジャンプ命令追加。その前にvm.rbをいじっておく。getCodeをgetCode8という名前に変え更にgetSignedCode8というメソッドを追加する。これに伴いMoveRImm8やAddALImm8で呼び出しているgetCodeをgetCode8に直す必要がある

def getCode8(index = 0)
    return @memory[@registers[EIP] + index].ord
end
    
def getSignedCode8(index = 0)
    value = getCode8(index)
    if value & 0x80 > 0 then
        value = -((~value + 1) & 0xFF)
    end
        
    return value
end

getSignedCode8は符号付き整数を返すようにしたgetCode8である。

次にジャンプ命令を実装する。今回はショートジャンプで、現在のプログラムカウンタ(EIP)をgetSignedCode8分だけ増加(getSignedCode8が負数を返せば減少する)させるものである。そして、ジャンプした値に命令長である2を追加する必要がある

class ShortJump8
    def execute(vm)
        vm.addEIP(vm.getSignedCode8(1))
        vm.addEIP(2)
    end
end

最後にInstructionMap.rb。ジャンプ命令を追加しておく

require "./vm/instruction/add/AddALImm8.rb"
require "./vm/instruction/jump/ShortJump8.rb"
require "./vm/instruction/move/MoveRImm8.rb"

class InstructionMap
    def initialize()
        @instructions = Array.new(256)
        
        @instructions[0x04] = AddALImm8.new()
        
        for i in 0..7
            @instructions[0xB0 + i] = MoveRImm8.new(i)
        end
        
        @instructions[0xEB] = ShortJump8.new()
    end
    
    def getInstruction(code)
        return @instructions[code]
    end
end

今回のジャンプ命令の実装でaddに含まれる全ての命令を実行することができる。最終的に無限ループするので、コンソール上には何度も同じ内容が表示される。次回こそはフラグレジスタの更新を行う…はず