今までメソッドの名前があまりにもJavaだったため、Rubyっぽく修正した。主にgetCode8のような名前だったのがget_code8になっている。また、オブジェクト自体に変更を加えるメソッドの最後に!を付けたり、まだ存在してないが真偽を返すメソッドは最後に?を付けるようにした。変更のあったファイルを載せておく
require "./vm/instruction/InstructionMap.rb" require "./vm/register/RegisterIndex.rb" require "./vm/exception/Exception.rb" include RegisterIndex class VM def initialize(memorySize) @registers = Array.new(REGISTER_COUNT); @memory = Array.new(memorySize); @instructions = InstructionMap.new() for i in 0..REGISTER_COUNT - 1 @registers[i] = 0 end 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 execute!() code = get_code8() instruction = @instructions.getInstruction(code) if instruction == nil then raise NotImplementedException, "Not Implmeneted 0x" << code.to_s(16) end instruction.execute(self) #命令コードと実行したクラスを表示 puts "0x" << code.to_s(16) << ": " << instruction.class().to_s() end def get_code8(index = 0) return @memory[@registers[EIP] + index].ord end def get_signed_code8(index = 0) value = get_code8(index) if value & 0x80 > 0 then value = -((~value + 1) & 0xFF) end return value end def get_register8(index) if index < 4 then return get_register8_low(index) else return get_register8_high(index - 4) end end def get_register8_low(index) return @registers[index] & 0xFF end def get_register8_high(index) return (@registers[index] >> 8) & 0xFF end #8bitレジスタに値を設定する。indexが4未満かどうかで呼び出すメソッド分岐 def set_register8!(index, data) if index < 4 then set_register8_low!(index, data) else set_register8_high(index - 4, data) end end #下位8bitレジスタに値を設定する def set_register8_low!(index, data) @registers[index] &= 0xFFFFFF00; @registers[index] |= (data & 0xFF); end #上位8bitレジスタに値を設定する def set_register8_high!(index, data) @registers[index] &= 0xFFFF00FF; @registers[index] |= (data & 0xFF) << 8; end def add_eip!(value) @registers[EIP] += value end end
./vm/register/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 REGISTER_COUNT = 15 end
./vm/instruction/add/AddALImm8.rb
require "./vm/register/RegisterIndex.rb" include RegisterIndex class AddALImm8 def execute(vm) al = vm.get_register8(EAX) al += vm.get_code8(1) vm.set_register8!(EAX, al) vm.add_eip!(2) end end
./vm/instruction/move/MoveRImm8.rb
class MoveRImm8 def initialize(index) @index = index end def execute(vm) vm.set_register8!(@index, vm.get_code8(1)) vm.add_eip!(2); end end
./vm/instruction/jump/ShortJump8.rb
class ShortJump8 def execute(vm) vm.add_eip!(vm.get_signed_code8(1)) vm.add_eip!(2) end end
./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]) loop do vm.execute!() end