2014-02-02

## 【深入淺出教你寫編譯器（Compiler）】五、虛擬機（Virtual Machine）

Arithmetic
subtract sub \$1,\$2,\$3 \$1 = \$2 – \$3
mult mult \$1,\$2,\$3 \$1 = \$2 * \$3
div div \$1,\$2,\$3 \$1 = \$2 / \$3
modulo mod \$1,\$2,\$3 \$1 = \$2 % \$3
subtract immediate subi \$1,\$2,100 \$1 = \$2 – 100
multiply immediate multi \$1,\$2,100 \$1 = \$2 * 100
divide immediate divi \$1,\$2,100 \$1 = \$2 / 100
modulo immediate modi \$1,\$2,100 \$1 = \$2 % 100
Logical
and and \$1,\$2,\$3 \$1 = \$2 & \$3 Logical AND
or or \$1,\$2,\$3 \$1 = \$2 | \$3 Logical OR
Data transfer
move data from register to another register move \$1,\$2 \$1 = \$2
load data lwi \$1,100 \$1 = 100
load upper immediate lui \$1,100 \$1 = 100 * 2^16
Conditional branch
define LABEL label LABEL LABEL:
branch on equal beq \$1,\$2,LABEL if (\$1 == \$2) goto LABEL
branch on not equal bne \$1,\$2,LABEL if (\$1 != \$2) goto LABEL
branch on less than bl \$1,\$2,LABEL if (\$1 < \$2) goto LABEL
branch on greater than bg \$1,\$2,LABEL if (\$1 > \$2) goto LABEL
branch on less than or equal ble \$1,\$2,LABEL if (\$1 <= \$2) goto LABEL
branch on greater than or equal bge \$1,\$2,LABEL if (\$1 >= \$2) goto LABEL
Unconditional jump
jump j LABEL goto LABEL
Others
print print \$1 print \$1

opcode1 operand1, operand2, operand3;

opcode2 operand1, operand2;

 1234567891011121314151617181920212223242526272829303132 `Wemachine.prototype.resolveRegister = ``function` `(operand){``    ``if` `(``typeof` `operand == ``"string"` `&& operand.length > 0){``        ``if` `(operand[0] == ``"\$"``){``            ``return` `parseInt(operand.substr(1));``        ``}``    ``}``    ``Errors.push({``        ``type: Errors.RUNTIME_ERROR,``        ``msg: ``"Fail to resolve register"``,``        ``line: 0``    ``});``    ``return` `-1;``}``Wemachine.prototype.getRegisterContent = ``function` `(operand){``    ``operand = ``this``.resolveRegister(operand);``    ``if` `(operand != -1){``        ``if` `(``this``.registers.length > operand){``            ``return` `this``.registers[operand];``        ``}``    ``}``    ``return` `0;``}``Wemachine.prototype.setRegisterContent = ``function` `(operand, value){``    ``operand = ``this``.resolveRegister(operand);``    ``if` `(operand != -1){``        ``this``.registers[operand] = value;``    ``}``}`

 123456 `Wemachine.prototype.run = ``function` `(){``    ``for` `(``var` `i = 0, l = ``this``.instructions.length; i < l; i++){``        ``var` `instruction = ``this``.instructions[i];``        ``this``[instruction.opcode].apply(``this``, instruction.operands);``    ``}``}`

 12345678 `Wemachine.prototype.lwi = ``function` `(operand1, operand2){``    ``this``.setRegisterContent(operand1, parseInt(operand2));``}``Wemachine.prototype.print = ``function` `(operand1){``    ``var` `val = ``this``.getRegisterContent(operand1);``    ``log(val);``}`

 123456789 `Wemachine.prototype.move = ``function` `(operand1, operand2){``    ``this``.setRegisterContent(operand1, ``this``.getRegisterContent(operand2));``}``Wemachine.prototype.lwi = ``function` `(operand1, operand2){``    ``this``.setRegisterContent(operand1, parseInt(operand2));``}``Wemachine.prototype.lui = ``function` `(operand1, operand2){``    ``this``.setRegisterContent(operand1, parseInt(operand2) << 16);``}`

Logical 跟 Arithmetic 的處理方法很相似，這裏就不著墨了。現在到最後要寫 branch 和 jump 了，要實現這個功能，我們要改變一下程式執行的方法，記得我們的 run method 嗎？我們的 run method 是用 i 來做 loop counter 的，現在要改變一下了，要用 program counter 取代 i，這樣我們才可以在其他方法中改變運行次序。

 1234567891011121314151617 `Wemachine.prototype.bne = ``function` `(operand1, operand2, operand3){``    ``var` `nextPC = ``this``.labelMap[operand3];``    ``if` `(nextPC == ``null``){``        ``Errors.push({``            ``type: Errors.RUNTIME_ERROR,``            ``msg: ``"Label not found"``,``            ``line: 0``        ``});``    ``}``else``{``        ``var` `val1 = ``this``.getRegisterContent(operand1);``        ``var` `val2 = ``this``.getRegisterContent(operand2);``        ``if` `(val1 != val2){``            ``this``.pc = nextPC;``        ``}``    ``}``}`

0条评论

×

¥.00

• 正文一键打印

• 全站无广告

• 全屏阅读

• 全站电子书免费读