x86エミュレータを作りたいと前にブログに書いたが、何をすればいいかわからなかった。しかし、とりあえず以前書いたプログラムを実行できればいいなと思い、先頭から8バイトぐらいまで実行できるようにしてみた。とりあえず、512バイト読み込んで、でてきた命令だけ実装。INT 0x10は無視した。それでレジスタに見立てた変数を少し用意して7命令だけ実行した後、レジスタもどきの変数の内容を表示するようにした。なぜかJavaで。そのうち挫折するだろうから挫折するまで続けたい
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class VMTest{ int eax, ebx, ecx, edx, eip; byte[] buff; public static void main(String[] args) throws IOException{ VMTest vm = new VMTest(); vm.load("Color"); vm.execute(); vm.execute(); vm.execute(); vm.execute(); vm.execute(); vm.execute(); vm.execute(); vm.printRegisters(); } public VMTest(){ buff = new byte[512]; eax = 0; ebx = 0; ecx = 0; edx = 0; eip = 0; } public void load(String fileName) throws IOException{ BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileName)); in.read(buff); in.close(); } public void execute(){ long op1, op2; int code = buff[eip] & 0xFF; System.out.println("execute... " + Integer.toHexString(code)); if(code == 0xB0){ op1 = buff[eip + 1]; eax &= 0xFFFFFF00; eax |= op1; eip += 2; }else if(code == 0xB4){ op1 = buff[eip + 1]; eax &= 0xFFFF00FF; eax |= (op1 << 8); eip += 2; }else if(code == 0xBA){ op1 = (buff[eip + 1] << 8) + buff[eip + 2]; edx &= 0xFFFF0000; edx |= op1; eip += 3; }else if(code == 0xCD){ op1 = buff[eip + 1]; if(op1 == 0x10){ int ah = (eax >> 8) & 0xFF; if(ah == 0x03){ } } eip += 2; } } public void printRegisters(){ System.out.println("EAX = " + eax); System.out.println("EBX = " + ebx); System.out.println("ECX = " + ecx); System.out.println("EDX = " + edx); System.out.println("EIP = " + eip); } }