Virtual stack machine 만들기
< instruction set >
opcode |
mnemonic |
instruction |
arg? |
function |
Arithmetic | ||||
1 | ADD | Add | n | Add the top two values on the stack |
2 | SUB | Subtract | n | Subtract the top of stack from the value below it. |
3 | MUL | Multiply | n | Multiply the top two values on the stack. |
4 | DIV | Divide | n | Divide the second value on the stack by the top one. Truncate and discard the remainder(like Pascal's DIV operation). |
5 |
NEG |
Negate | n | Negate the top of the stack. |
Boolean | ||||
6 |
CMPNE |
Not Equal |
n |
if the top two items on the stack are not equal, push a 1 else push a 0. |
7 | CMPEQ |
Equal |
n | if the top two items on the stack are equal, push a 1 else push a 0. |
8 | CMPLT | Less | n | if the top of the stack is less than the value below it, push a 1 else push a 0. |
9 | CMPGT | Greater | n | if the top of the stack is greater than the value below it, push a 1 else push a 0. |
10 | CMPGE |
Greater or equal |
n | if the top of the stack is greater than or equal to the value below it, push a 1 else push a 0. |
11 | CMPLE |
Less or equal |
n | if the top of the stack is less than or equal to the value below it, push a 1, else push a 0. |
12 | CMPZR | Zero | n | if the top of the stack is 0, replace it with 1 else replace it with 0 |
Stack Manipulation | ||||
13 | PUSHC | Push constant | y | Put the argument on the stack |
14 | PUSH | Push addr | y | Put the contents of the location specified by the argument on the stack |
15 | POPC | Pop constant | y | Put the top of the stack into the location specified by the argument |
16 | POP | Pop | n | Put the second value on the stack into the location specified by the top of the stack |
Control | ||||
17 | BRANCH | Branch | y | Set the program counter to the location specified by the argument |
18 | JUMP | Jump | n | Set the program counter to the top of stack |
19 | BREQ |
Branch if equal |
y | if the top of the stack is 0, branch to the argument |
20 | BRLT | Branch if less | y | if the top of the stack is less than 0, branch to the argument |
21 | BRGT | Branch if greater | y | if the top of the stack is greater than 0, branch to the argument |
Input / Output | ||||
22 | RDCHR |
Read char |
n | Read a character from the keyboard and put its ASCII value on the stack |
23 | RDINT | Read int | n | Read an integer from the keyboard and put it on the stack |
24 | WRCHR | Write char | n | Write the top of the stack to the screen treating it as an ASCII value. |
25 | WRINT | Write int | n | Write the top of the stack to the screen treating if as a signed integer. |
Miscellaneous | ||||
26 | CONTS | Contents | n |
Replace the top of stack with the contents of the location specified by the top of stack |
27 | HALT | Halt | n | Stop the machine |
< op code 형식 >
Header Record, Text Record, End Record 세 종류
Header Record 형식:
H 프로그램_이름
Text Record 형식( Text Record는 여러 줄이 될 수 있음):
T Op_코드의_시작_주소 Text_Record의_길이 코드_Text
, 여기서 Text는 10진수로 구성된다.
End Record 형식:
E 명령어의_시작_주소
ex)
H TEST1
T 0 9 5 10 14 0 14 1 1 25 27
E 2
< 구현 >
/* 코드실행의 기본인 fetch - decode - execute 대로 구현함 */
public class MyVSM {
private VSMMemory memory;
private int programCtr;
private int stackPtr;
private int stackLimit;
...
public MyVSM(int memorySize){
memory = new VSMMemory(memorySize);
}
public void loadProgram(String filename) {
VSMOpcodeLoader loader = new VSMOpcodeLoader(filename);
loader.loadTo(memory);
programCtr = loader.getStartAddress();
stackPtr = (memory.getSize()-1);
stackLimit = loader.getEndOfProram();
}
public void startProgram() {
short fetchedOpcode = 0;
while( !isEnd ){
// fetch
fetchedOpcode = fetch();
// decode (and execute)
decodeAndExecute(fetchedOpcode);
}
}
...
}
/* 단순히 워드(구현상 short) 배열 관리클래스 */
public class VSMMemory {
private int size;
// memory type 'WORD' as short
private short[] memorySpace;
public VSMMemory(int size){
this.size = size;
memorySpace = new short[size];
}
...
public short accessAt(int address) {
if( address < 0 || size <= address)
throw new VSMMemAccessViolationException();
return memorySpace[address];
}
public void assignTo(int address, short value) {
if( address < 0 || size <= address)
throw new VSMMemAccessViolationException();
memorySpace[address] = value;
}
...
}
/* opcode를 읽어 타겟 메모리에 적재해주는 역할 */
public class VSMOpcodeLoader {
private VSMMemory targetMemory;
private FileReader reader;
private int lookahead = 0;
...
public VSMOpcodeLoader(String fileName) {
reader = new FileReader(fileName);
}
public void loadTo(VSMMemory memory) {
targetMemory = memory;
while((lookahead = reader.read()) != -1){
if(lookahead == '\r' || lookahead == '\n' || lookahead == '\t' || lookahead == ' ')
continue;
if(lookahead == 'H')
parseName();
else if(lookahead == 'T')
parseTextRecord();
else if(lookahead == 'E')
parseEndRecord();
}
}
...
}
물론 실제 vm은 무진장 복잡하겠지만,, 기본은 똑같지않을까 싶다.
'Note..' 카테고리의 다른 글
libpng example link (0) | 2014.05.02 |
---|---|
water jug problem (0) | 2013.06.18 |
Unity 3d Instantiate type (0) | 2013.03.09 |
[DB] Newheart Academy DB - 4주차 ppt (0) | 2013.02.28 |
[DB] Newheart Academy DB - 3주차 ppt (0) | 2013.02.16 |