如今来模拟一下 CPU 执行机器指令的状况,因为汇编代码和机器指令一一对应,因此咱们能够建立一个直接执行汇编代码的模拟器。
在建立模拟器前,先来说解一下相关指令的操做。git
在内存中,栈的特色是只能在同一端进行插入和删除的操做,即只有 push 和 pop 两种操做。github
push 指令的做用是将一个操做数推入栈中。this
pop 指令的做用是将一个操做数弹出栈。prototype
add 指令的做用是执行两次 pop 操做,弹出两个操做数 a 和 b,而后执行 a + b,再将结果 push 到栈中。code
sub 指令的做用是执行两次 pop 操做,弹出两个操做数 a 和 b,而后执行 a - b,再将结果 push 到栈中。token
mul 指令的做用是执行两次 pop 操做,弹出两个操做数 a 和 b,而后执行 a * b,再将结果 push 到栈中。ip
sub 指令的做用是执行两次 pop 操做,弹出两个操做数 a 和 b,而后执行 a / b,再将结果 push 到栈中。内存
四则运算的全部指令已经讲解完毕了,是否是以为很简单?get
注意:须要引入前两篇文章词法分析和语法分析的代码编译器
function CpuEmulator(instructions) { this.ins = instructions.split('\r\n') this.memory = [] this.re = /^(push)\s\w+/ this.execute() } CpuEmulator.prototype = { execute() { this.ins.forEach(i => { switch (i) { case 'add': this.add() break case 'sub': this.sub() break case 'mul': this.mul() break case 'div': this.div() break default: if (this.re.test(i)) { this.push(i.split(' ')[1]) } } }) }, add() { const b = this.pop() const a = this.pop() this.memory.push(a + b) }, sub() { const b = this.pop() const a = this.pop() this.memory.push(a - b) }, mul() { const b = this.pop() const a = this.pop() this.memory.push(a * b) }, div() { const b = this.pop() const a = this.pop() this.memory.push(a / b) }, push(x) { this.memory.push(parseInt(x)) }, pop() { return this.memory.pop() }, getResult() { return this.memory[0] } } const tokens = lexicalAnalysis('(100+ 10)* 10-100/ 10 +8* (4+2)') const writer = new AssemblyWriter() const parser = new Parser(tokens, writer) const instructions = parser.getInstructions() const emulator = new CpuEmulator(instructions) console.log(emulator.getResult()) // 1138