如今來模擬一下 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