📄 vcpu.java
字号:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Vcpu {
private Memory mem;
static long eip;
public Vcpu(Memory mem, long eip) {
this.mem = mem;
Vcpu.eip = eip;
}
public Vcpu(Memory mem) {
this.mem = mem;
Vcpu.eip = Memory.CODEBASE;
}
public Vcpu() {
}
public void reset(Memory mem){
Vcpu.eip = Memory.CODEBASE;
this.mem=mem;
}
// loader .exe file
public boolean loader(File exeFile) throws IOException {
FileInputStream ins = new FileInputStream(exeFile);
InputStreamReader in = new InputStreamReader(ins);
BufferedReader bin = new BufferedReader(in);
String tmp;
long codeaddr = Memory.CODEBASE;
while ((tmp = bin.readLine()) != null) {
if (codeaddr < Memory.MAXADDR) {
mem.loader(codeaddr++, tmp);
} else {
return false;
}
}
mem.loader(codeaddr, "exit");
return true;
}
//start cpu
public void start(){
String instruction;
while(!(instruction=this.fetch()).equals("exit")){
// System.out.println(instruction);
this.execute(instruction);
}
System.out.println("Exit :)");
}
// fetch instruction
public String fetch() {
System.out.print("eip=0x"+Long.toHexString(Vcpu.eip)+" :");
String instruction = mem.read(Vcpu.eip++);
System.out.println(instruction);
return instruction;
}
public void test(){
}
// decode instruction
public OpType decode(String instruction) {
String opstr = instruction.substring(instruction.length() - 3,
instruction.length());
// int opcodeINT = Integer.parseInt(opstr);
// OpType opType;
if (opstr.equals("000")) {
return OpType.MOVL;
} else if (opstr.equals("001")) {
return OpType.ADDL;
} else if (opstr.equals("010")) {
return OpType.SUBL;
} else if (opstr.equals("011")) {
return OpType.MULL;
} else if (opstr.equals("100")) {
return OpType.PRINT;
} else
return null;
}
// execute instruction
public void execute(String instruction) {
OpType opcode = this.decode(instruction); // decode instruction
OprandFlag flag = this.getFlag(instruction); // get flag of first
String firstOprandStr = this.getFirstOprand(instruction, flag);
Long secondOprandAddr = this.getSecondOprand(instruction);
String secOprandStr;
Long secondOprand;
if (opcode != null) {
switch (opcode) {
case MOVL:
this.mem.write(secondOprandAddr, firstOprandStr);
break;
case ADDL:
secOprandStr = this.mem.read(secondOprandAddr);
secondOprand = this.strDataToLong(secOprandStr);
secondOprand += this.strDataToLong(firstOprandStr);
this.mem.write(secondOprandAddr, this
.LongDataToStr(secondOprand));
break;
case SUBL:
secOprandStr = this.mem.read(secondOprandAddr);
secondOprand = this.strDataToLong(secOprandStr);
secondOprand = this.strDataToLong(firstOprandStr)-secondOprand;
this.mem.write(secondOprandAddr, this
.LongDataToStr(secondOprand));
break;
case MULL:
secOprandStr = this.mem.read(secondOprandAddr);
secondOprand = this.strDataToLong(secOprandStr);
secondOprand *= this.strDataToLong(firstOprandStr);
this.mem.write(secondOprandAddr, this
.LongDataToStr(secondOprand));
break;
case PRINT:
Long firstOprand = this.strDataToLong(firstOprandStr);
System.out.println("Result:"+firstOprand);
break;
}
}
}
// get the flag of first oprand
public OprandFlag getFlag(String instruction) {
char flag = instruction.charAt(instruction.length() - 4);
if (flag == '0') {
return OprandFlag.ID;
} else if (flag == '1') {
return OprandFlag.NUM;
}
return null;
}
// get first oprand
public String getFirstOprand(String instruction, OprandFlag flag) {
String firstOprand = instruction.substring(14, 28);
if ((flag != null) && flag.equals(OprandFlag.ID)) {
Long addr = this.strAddrToLong(firstOprand);
return this.mem.read(addr);
} else if ((flag != null) && flag.equals(OprandFlag.NUM)) {
return firstOprand;
}
return null;
}
// get second oprand
public Long getSecondOprand(String instruction) {
String secondOprand = instruction.substring(0, 14);
return this.strAddrToLong(secondOprand);
}
// translate String addr to long addr
public Long strAddrToLong(String strAddr) {
char[] addr = strAddr.toCharArray();
char tmp;
Long addrLong = 0L;
int tag;
int size = addr.length;
for (int i = 0; i < size; i++) {
tmp = addr[i];
tag = size - 1 - i;
if (tmp == '1') {
addrLong += (long) Math.pow(2, tag);
}
}
return addrLong;
}
// translate Data string to long;
public Long strDataToLong(String strData) {
char[] data = strData.toCharArray();
int leng = data.length;
if (data[0] == '0') {
return this.strAddrToLong(strData);
} else {
Long tmp = (long) Math.pow(2, leng) - this.strAddrToLong(strData);
return 0 - tmp;
}
}
// translate Data long to string
public String LongDataToStr(Long data) {
String strData = Long.toBinaryString(data);
String subStr=strData;
if(strData.length()<32){
subStr=strData;
int rest=32-strData.length();
for(int i=0;i<rest;i++){
subStr="0"+strData;
}
}else if(strData.length()>32){
subStr=strData.substring(32, 64);
}
return subStr;
}
public Memory getMem() {
return mem;
}
public void setMem(Memory mem) {
this.mem = mem;
}
public long getEip() {
return eip;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -