IWKS 3300: NAND to Tetris Spring 2019 John K. Bennett Virtual Machine Part I: Stack Arithmetic Foundations of Global Networked Computing: Building a Modern Computer From First Principles This course is based upon the work of Noam Nisan and Shimon Schocken. More information can be found at (www.nand2tetris.org).
Error in the Book (pg. 138, Figure 7.10) As printed: local pointer that local pointer that X 4315 4315 4317 19 … … … … Should be: local pointer that local pointer that 4315 4315 19 … … … … 4317 Also, in text on page 139, and in Fig. 11 on pg. 140: replace “ b.radius = 17 ” with “ b.radius.r ” (the value of r is 17)
Where We Are Software Hierarchy Abstract design Human You are here abstract interface Thought Chapters 9, 12 Compiler H.L. Language & abstract interface Chapters 10 - 11 Operating Sys. VM Translator Virtual abstract interface Machine Chapters 7 - 8 Assembly Language Assembler Chapter 6 abstract interface Computer Architecture Machine abstract interface Code Chapters 4 - 5 Gate Logic Hardware abstract interface Platform Chapters 1 - 3 Electrical Engineering Chips & Physics Logic Gates Hardware Hierarchy
Motivation Hack code Jack code (example) 0000000000010000 class Main { 1110111111001000 Our ultimate goal: static int x; 0000000000010001 1110101010001000 Translate high-level function void main() { 0000000000010000 // Inputs and multiplies two numbers 1111110000010000 programs into 0000000000000000 var int a, b, x; executable code. 1111010011010000 let a = Keyboard.readInt(“Enter a number”); 0000000000010010 let b = Keyboard.readInt(“Enter a number”); 1110001100000001 let x = mult(a,b); 0000000000010000 Compiler return; 1111110000010000 } 0000000000010001 0000000000010000 } 1110111111001000 0000000000010001 // Multiplies two numbers. 1110101010001000 function int mult(int x, int y) { 0000000000010000 var int result, j; 1111110000010000 let result = 0; let j = y; 0000000000000000 while ~(j = 0) { 1111010011010000 let result = result + x; 0000000000010010 let j = j – 1; 1110001100000001 0000000000010000 } 1111110000010000 return result; 0000000000010001 } ... }
Different Compilation Models direct compilation: 2-tier compilation: . . . . . . language 1 language 2 language n language 1 language 2 language n intermediate language . . . hardware hardware hardware . . . hardware hardware hardware platform 1 platform 2 platform m platform 1 platform 2 platform m . requires n m translators requires n + m translators Two-tier compilation: First compilation stage: depends only on the details of the source language Second compilation stage: depends only on the details of the target language.
Using Intermediate Code language . . . . . . Jack Some Intermediate Code: Some Other language language The interface between the two compilation Jack Some stages Some Other compiler compiler compiler Should be sufficiently general to support several Intermediate code <high-level language, machine-language> VM VM imp. pairs implementation VM imp. VM over the Hack over CISC over RISC emulator platform Can be modeled as the platforms platforms language of an abstract virtual machine (VM) CISC RISC written in Hack . . . Can typically be machine machine a high-level machine language language language language implemented in several different ways . . . . . . CISC Hack RISC other digital platforms, each equipped Any computer machine machine computer with its own VM implementation
Focus of Project 7 (yellow) : . . . . . . Jack Some Some Other Book chapters and language language language course projects: 9, 10, 11, 12 Jack Some Some Other compiler compiler compiler VM language VM VM imp. implementation VM imp. (this, and the VM 7, 8 over the Hack over CISC over RISC emulator next project) platform platforms platforms CISC RISC written in Hack . . . machine machine a high-level machine language language language language 1, 2, 3, 4, 5, 6 . . . . . . Hack CISC RISC other digital platforms, each equipped Any computer machine machine with its VM implementation computer
The Hack VM Model and Language Other VM models (e.g., Java JVM/JRE, .NET’s IL/CLR and Pascal PCode) are similar in nature, but differ in scope and details. Several different ways to think about the notion of a virtual machine: Abstract software engineering view: the VM is an interesting and useful abstraction Practical software engineering view: the VM code layer enables “ managed code ” (e.g., enhanced security) Pragmatic compiler writing view: a VM architecture makes writing a compiler much easier (as we will see later in the course) Opportunistic empire builder view: a VM architecture allows writing high-level code once and have it run on many target platforms with little or no modification (think Sun/Oracle vs. Microsoft)
Our Game Plan Goal: Specify and implement a VM model and language: Arithmetic / Boolean commands Program flow commands add label (declaration) sub goto (label) neg if-goto (label) eq gt Next Week Today lt Function calling commands and or function (declaration) not call (a function) Memory access commands return (from a function) pop x (pop into x , a variable) push y (push y, a variable or constant) Our game plan today: (a) describe the VM abstraction (above) (b) suggest how to implement it over the Hack platform.
The Hack VM is a Stack-based Machine All operations are performed on the stack Data is stored to and from the stack to several separate memory segments All memory segments have the same access semantics One of the memory segments m is called static , and we will use it (as an arbitrary example) in the following examples:
Hack VM Data Types The VM has a single 16-bit data type that can be used as: (16-bit 2 ’ s complement: -32768, ... , 32767), an integer value a Boolean value (-1 and 0, representing true and false, respectively), or a a pointer (memory address) The stack grows “ higher ” in memory:
VM Stack Memory Access Operations Stack static Stack static push 121 0 5 121 0 5 static 2 5 1 12 5 1 12 17 2 3 17 2 3 SP 3 -532 3 3 -532 ... ... ... ... SP (before) (after) Stack static Stack static pop 121 0 5 121 0 17 static 0 5 1 12 5 1 12 17 2 3 2 3 SP SP 3 -532 3 -532 ... ... ... ... The stack: A classic LIFO data structure Elegant and powerful Several hardware / software implementation options
Example of Stack Evaluation of Arithmetic Expression // z=(2-x)-(y+5) push 2 (suppose that push x x refers to static 0 , sub y refers to static 1 , and push y push 5 z refers to static 2 ) add sub Note: as shown here, the stack pointer is incremented pop z after a push, and is thus “ ready ” for the next push. Can you think of another option? static Stack x 5 sub SP push 2 2 push x 2 y 9 SP 5 . . . SP -3 -3 -3 add push y push 5 9 SP 9 SP 5 SP Stack static -17 -3 SP x 5 pop z sub 14 SP y 9 SP z -17 . . .
Evaluation of Boolean Expressions // ((x<7) || (y=8)) (suppose that push x push 7 x refers to static 0 , and lt y refers to static 1 ) push y push 8 eq or static Stack x 12 12 12 SP lt push x push 7 y 8 7 SP . . . SP false false false eq push y push 8 8 SP 8 SP 8 SP true false (In the Hack VM, true and or SP true false are represented as -1 SP and 0 , respectively)
Arithmetic and Boolean Operations in the Hack VM Language In every case, all operands are popped off of the stack, and any result is pushed onto the stack.
VM Memory Segments A VM program is designed to provide an intermediate abstraction of a program written in some high-level language Modern object-oriented high-level languages normally include a variety of variable types: Class level: Static variables (class variables) Private variables (sometimes called “ fields ” or “ properties ” ) Method / function level: Local variables Argument variables When translated into the VM language, The static, private, local and argument variables are mapped by the compiler on the four memory segments: static , this , local , argument In addition, there are four other memory segments: that , constant , pointer , temp
VM Memory Segments and Memory Access Commands The VM abstraction includes 8 separate memory segments named: static , this , local , argument , that , constant , pointer , temp All memory segments are accessed in the same way using the same generic syntax: Memory access VM commands: pop memorySegment index push memorySegment index Where memorySegment is static , this , local , argument , that , constant , pointer , or temp And index is a non-negative integer In all our code examples thus far, memorySegment has been static . At the VM abstraction level, all memory segments are treated the same way.
Recommend
More recommend