CPU Emulator Tutorial
CPU Emulator Tutorial
Tutorial Index
Slide 1/40
Background
The Elements of Computing Systems evolves around
the construction of a complete computer system, done in the framework of a 1- or 2-semester course. In the first part of the book/course, we build the hardware platform of a simple yet powerful computer, called Hack. In the second part, we build the computers software hierarchy, consisting of an assembler, a virtual machine, a simple Java-like language called Jack, a compiler for it, and a mini operating system, written in Jack. The book/course is completely self-contained, requiring only programming as a pre-requisite. The books web site includes some 200 test programs, test scripts, and all the software tools necessary for doing all the projects.
Tutorial Index
Slide 2/40
Simulators
(HardwareSimulator, CPUEmulator, VMEmulator):
This tutorial is about the CPU emulator.
Other
Bin: simulators and translators software; builtIn: executable versions of all the logic
Tutorial Objective
Learn how to use the CPU Emulator for simulating the execution of machine language programs on the Hack computer
Tutorial Index
Slide 4/40
This CPU emulator simulates the operations of the Hack computer, built in chapters 1-5 of the book. Hack -- a 16-bit computer equipped with a screen and a keyboard -resembles hand-held computers like game machines, PDAs, and cellular telephones. Before such devices are actually built in hardware, they are planned and simulated in software. The CPU emulator is one of the software tools used for this purpose.
Tutorial Index
Slide 5/40
I.
Basic Platform
II. I/O devices III. Interactive simulation IV. Script-based simulation V. Debugging
Relevant reading (from The Elements of Computing Systems): Chapter 4: Chapter 5: Machine Language Computer Architecture
Tutorial Index
Slide 6/40
Tutorial Index
Slide 7/40
Travel Advice: This tutorial includes some examples of programs written in the Hack machine language (chapter 4). There is no need however to understand either the language or the programs in order to learn how to use the CPU emulator. Rather, it is only important to grasp the general logic of these programs, as explained (when relevant) in the tutorial.
Tutorial Index
Slide 8/40
screen
registers
ALU
Tutorial Index
Slide 9/40
Instruction memory
The loaded code can be viewed either in binary, or in symbolic notation (present view)
Tutorial Index
Slide 10/40
Data memory (32K RAM), used for: General-purpose data storage (variables, arrays, objects, etc.) Screen memory map Keyboard memory map
Address (A) register, used to: Select the current RAM location OR Set the Program Counter (PC) for jumps (relevant only if the current instruction includes a jump directive).
Tutorial Index
Slide 11/40
Registers
Registers (all 16-bit): D: Data register A: Address register M: Stands for the memory register
whose address is the current value of the Address register
M (=RAM[A]) D
Tutorial Index
Slide 12/40
Arithmetic/Logic Unit
Arithmetic logic unit (ALU)
The ALU can compute various arithmetic and logical functions (lets call them f) on subsets of the three registers {M,A,D} All ALU instructions are of the form {M,A,D} = f ({M,A,D}) (e.g. M=M-1, MD=D+A , A=0, etc.) The ALU operation (LHS destination, function, RHS operands) is specified by the current instruction. D
Current instruction
M (=RAM[A])
Tutorial Index
Slide 13/40
Tutorial Index
Slide 14/40
Tutorial Index
Slide 15/40
Tutorial Index
Slide 16/40
1. Click the keyboard enabler 2. Press some key on the real keyboard, say S
Tutorial Index
Slide 17/40
The emulator displays Its character code in the keyboard memory map
Tutorial Index
Slide 18/40
Tutorial Index
Slide 19/40
Loading a program
Tutorial Index
Slide 20/40
Loading a program
Tutorial Index
Slide 21/40
Running a program
4. Watch here 2. Click the run button. 1. Enter a number, say 50. 3. To speed up execution, use the speed control slider
Programs description: Draws a rectangle at the top left corner of the screen. The rectangles width is 16 pixels, and its length is determined by the current contents of RAM[0]. Note: There is no need to understand the programs code in order to understand whats going on.
Tutorial Index
Slide 22/40
Running a program
4. Watch here 2. Click the run button. 1. Enter a number, say 50. 3. To speed up execution, use the speed control slider
Programs description: Draws a rectangle at the top left corner of the screen. The rectangles width is 16 pixels, and its length is determined by the current contents of RAM[0]. Note: There is no need to understand the programs code in order to understand whats going on.
Tutorial Index
Slide 23/40
Program action: Since RAM[0] happens to be 50, the program draws a 16X50 rectangle. In this example the user paused execution when there are 14 more rows to draw.
Programs description: Draws a rectangle at the top left corner of the screen. The rectangles width is 16 pixels, and its length is determined by the current contents of RAM[0]. Note: There is no need to understand the programs code in order to understand whats going on.
Tutorial Index
Slide 24/40
Animation options
Animation control: Program flow (default): highlights the current instruction in the instruction memory and the currently selected RAM location Program & data flow: animates all program and data flow in the computer No animation: disables all animation The simulator can animate both program flow and data flow Usage tip: To execute any non-trivial program quickly, select no animation.
Tutorial Index
Slide 25/40
Tutorial Index
Slide 26/40
Test scripts:
Are written in a Test Description Language (described in Appendix B) Can cause the emulator to do anything that can be done interactively, and quite a few things that cannot be done interactively.
CPU Emulator Tutorial, www.nand2tetris.org Tutorial Index Slide 27/40
Tutorial Index
Slide 28/40
Example: Max.asm
Note: For now, it is not necessary to understand either the Hack machine language or the Max program. It is only important to grasp the programs logic. But if youre interested, we give a language overview on the right.
// // Computes Computes M[2]=max(M[0],M[1]) M[2]=max(M[0],M[1]) where where M M stands stands for for RAM RAM @0 @0 D=M // D=M // D D= = M[0] M[0] @1 @1 D=D-M // D=D-M // D D= =D D- M[1] M[1] @FIRST_IS_GREATER @FIRST_IS_GREATER D;JGT // D;JGT // If If D>0 D>0 goto goto FIRST_IS_GREATER FIRST_IS_GREATER @1 @1 D=M // D=M // D D= = M[1] M[1] @SECOND_IS_GREATER @SECOND_IS_GREATER 0;JMP // 0;JMP // Goto Goto SECOND_IS_GREATER SECOND_IS_GREATER (FIRST_IS_GREATER) (FIRST_IS_GREATER) @0 @0 D=M // D=M // D=first D=first number number (SECOND_IS_GREATER) (SECOND_IS_GREATER) @2 @2 M=D // M=D // M[2]=D M[2]=D (greater (greater number) number) (INFINITE_LOOP) (INFINITE_LOOP) @INFINITE_LOOP @INFINITE_LOOP // // Infinite Infinite loop loop (our (our standard standard 0;JMP // 0;JMP // way way to to terminate terminate programs). programs).
CPU Emulator Tutorial, www.nand2tetris.org Tutorial Index
The other commands are selfexplanatory; Jump directives like JGT and JMP mean Jump to the address currently stored in the A register Before any command involving a RAM location (M), the A register must be set to the desired RAM address (@address) Before any command involving a jump, the A register must be set to the desired ROM address (@label).
Slide 29/40
The scripting language has commands for: Loading programs Setting up output and compare files Writing values into RAM locations Writing values into registers Executing the next command (ticktack) Looping (repeat) And more (see Appendix B). Notes: As it turns out, the Max program requires 14 cycles to complete its execution All relevant files (.asm,.tst,.cmp) must be present in the same directory. Output
| | RAM[0] RAM[0] | | RAM[1] RAM[1] | | RAM[2] RAM[2] | | | 15 | 32 | 32 | | 15 | 32 | 32 | | 47 | 22 | 47 | 47 | 22 | 47 | |
Slide 30/40
Load a script
Interactive loading of the tested program itself (.asm or .hack file) is typically not necessary, since test scripts typically begin with a load program command.
Tutorial Index
Slide 31/40
Speed control
Load a script Script = a series of simulation steps, each ending with a semicolon; Reset Important point: Whenever an assembly the script program (.asm file) is loaded into the emulator, the program is assembled on the Pause fly into the machine language code, and this is simulation the code that actually gets loaded. In the process, all comments and white space are Execute step after from the code, and all symbols removed step repeatedly resolve to the numbers that they stand for. Execute the next simulation step
Tutorial Index
Slide 32/40
View options: Script: Shows the current script; Output: Shows the generated output file; Compare: Shows the given comparison file; Screen: Shows the simulated screen. When the script terminates, the comparison of the script output and the compare file is reported.
Tutorial Index
Slide 33/40
Note that these run/stop buttons dont control the program. They control the script, which controls the computers clock, which causes the computer hardware to fetch and execute the programs instructions, one instruction per clock cycle.
If you load a program file without first loading a script file, the emulator loads a default script (always). The default script consists of a loop that runs the computer clock infinitely.
Tutorial Index
Slide 34/40
Part V: Debugging
Tutorial Index
Slide 35/40
Breakpoints: A breakpoint is a pair <variable, value> where variable is one of {A, D, PC, RAM[i], time} and i is between 0 and 32K. Breakpoints can be declared either interactively, or via script commands. For each declared breakpoint, when the variable reaches the value, the emulator pauses the programs execution with a proper message.
Tutorial Index
Slide 36/40
Breakpoints declaration
Tutorial Index
Slide 37/40
Breakpoints declaration
Tutorial Index
Slide 38/40
Breakpoints usage
3. When the A register will be 2, or RAM[20] will be 5, or 12 time units (cycles) will elapse, or RAM[21] will be 200, the emulator will pause the programs execution with an appropriate message. A powerful debugging tool!
Tutorial Index
Slide 39/40
Postscript: Maurice Wilkes (computer pioneer) discovers debugging: As soon as we started programming, we found to our surprise that it wasn't as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs. (Maurice Wilkes, 1949).
Tutorial Index
Slide 40/40