test 2 with only questions regarding jack code and vm code
Question: Describe how the stack works in the VM architecture and what happens during push/pop operations.
The stack is a LIFO (Last-In-First-Out) data structure that serves as the computational backbone of the VM architecture.
Stack advantages:
Classical LIFO data structure
Elegant and powerful for computational purposes
Can be implemented efficiently in both hardware and software
push takes things and puts it on the stack to prepare it for some sort of operation, pop takes things off the stack to store it for later or get it out of the way
Explain the implementation and purpose of different memory segments in the VM architecture.
The VM architecture uses several memory segments:
local: Base address stored in LCL register, used for function local variables
argument: Base address stored in ARG register, used for function arguments
this and that: Base addresses stored in THIS and THAT registers; THIS is used for object fields, THAT for array access
static: Variables mapped to RAM[16]...RAM[255], used for static (class) variables
constant: Read-only segment, generates constants 0,1,2,...
pointer: Maps directly to THIS (pointer 0) and THAT (pointer 1) registers
temp: Fixed segment mapped to RAM[5]...RAM[12]
Memory access operations follow the pattern:
push segment i // Pushes the value of segment[i] onto the stack
pop segment i // Pops the top stack value into segment[i]
Explain the purpose and components of the CodeWriter API in the VM-to-Assembly translator.
The CodeWriter API translates VM commands into Hack assembly code through these key routines:
writeInit: Writes bootstrap code (VM initialization) at the beginning of the output file
writeLabel(label): Translates the label
VM command
writeGoto(label): Translates the goto
VM command
writeIf(label): Translates the if-goto
VM command
writeCall(functionName, numArgs): Translates the call
VM command
writeReturn: Translates the return
VM command
writeFunction(functionName, numLocals): Translates the function
VM command
Describe how VM function-related commands are translated to assembly.
The translation of VM function commands involves:
For function f k:
Generate a label for the function entry point (f)
Generate code to initialize k local variables to 0
For call f n:
Save the return address and caller's state (LCL, ARG, THIS, THAT)
Reposition ARG pointer to point to the first argument
Reposition LCL pointer for the callee's local variables
Transfer control to function f
Add label for return address
For return:
Save the return value temporarily
Restore the caller's state (THAT, THIS, ARG, LCL)
Replace the call arguments with the return value
Jump to the saved return address
What are the noteworthy features of the Jack language as described in the course materials?
Jack has several unique (and sometimes cumbersome) features:
The let keyword is required for assignments: let x = 0;
The do keyword is required for method/function calls: do reduce();
No operator priority: Expressions are evaluated strictly left-to-right
1 + 2 * 3
yields 9
in Jack (not 7 as in most languages)
Use parentheses to enforce conventional precedence: 1 + (2 * 3)
Only three primitive data types: int, boolean, char (all treated as 16-bit values)
No type casting: Any type can be assigned to any variable without explicit conversion
Array declaration requires two steps: Array x;
followed by let x = Array.new();
Static methods are called function
while instance methods are called method
Constructors are called constructor
and invoked with ClassName.new(argsList)
How are arrays implemented and accessed in Jack?
Arrays in Jack involve these key points:
Declaration: Array arr;
Instantiation: let arr = Array.new(size);
(allocates memory for the array)
Access: let arr[i] = value;
or let value = arr[i];
In the VM implementation, array access is translated using the that
segment:
// Array[i] access (Jack: let val = arr[i];)
push arr // Base address
push i // Index
add // Calculate address (base + index)
pop pointer 1 // Set THAT segment to point to arr[i]
push that 0 // Get value from arr[i] pop local 0 // Store in val
The base address of the array is the value returned by Array.new()
, which is a pointer to the first element.
How are Jack's object-oriented features translated to VM code?
Jack's OO features are translated to VM as follows:
Class fields: Accessed via this
segment
// Jack: field int x;
// Access in method: let y = this.x;
push this 0 // Assuming x is the first field
pop local 0 // Store in y
Method calls: The object reference is passed as the first argument
// Jack: let result = obj.method(arg1, arg2);
push object-reference // 'this' for the called method
push arg1
push arg2
call Class.method 3 // 3 arguments including 'this'
pop result
Constructor: Allocates memory and initializes the object
// Jack: constructor Point new(int x, int y)
function Point.new 0
push constant 2 // Size (fields count)
call Memory.alloc 1 // Allocate memory
pop pointer 0 // Set THIS to point to the new object // Initialize fields
push argument 0 // x value pop this 0 // store in this.x
push argument 1 // y value
pop this 1 // store in this.y
push pointer 0 // Return this
return
How are Jack's control structures (if, while) translated to VM code?
ck control structures translate to VM as follows:
If Statement:
// Jack:
if (x > y) { statements1 } else { statements2 }
push x
push y
gt // x > y not // Negate for if-goto
if-goto ELSE_LABEL // Jump if condition is false // VM code for statements1
goto END_IF
label ELSE_LABEL // VM code for statements2
label END_IF
While Loop:
// Jack: while (condition) { statements } label WHILE_START // VM code for condition evaluation
not // Negate for if-goto
if-goto WHILE_END // Jump if condition is false // VM code for statements
goto WHILE_START // Loop back
label WHILE_END
Translate this to Jack Code: class Main {
function void main() {
var Array a;
var int i, sum;
let a = Array.new(5);
let i = 0;
let sum = 0;
while (i < 5) {
let a[i] = i * 2;
let i = i + 1;
}
let i = 0;
while (i < 5) {
let sum = sum + a[i];
let i = i + 1;
}
do Output.printInt(sum);
return;
}
}
function Main.main 3 // 3 local variables: a, i, sum
// let a = Array.new(5);
push constant 5
call Array.new 1
pop local 0
// let i = 0;
push constant 0
pop local 1
// let sum = 0;
push constant 0
pop local 2
// while (i < 5) {
label WHILE_1
push local 1
push constant 5
lt
not
if-goto END_WHILE_1
// let a[i] = i * 2;
push local 0 // base address of array a
push local 1 // i
add // calculate a[i] address
push local 1 // i
push constant 2
call Math.multiply 2 // i * 2
pop temp 0 // temporary store result
pop pointer 1 // set THAT to a[i]
push temp 0 // restore result
pop that 0 // a[i] = i * 2
// let i = i + 1;
push local 1
push constant 1
add
pop local 1
goto WHILE_1
label END_WHILE_1
// let i = 0;
push constant 0
pop local 1
// while (i < 5) {
label WHILE_2
push local 1
push constant 5
lt
not
if-goto END_WHILE_2
// let sum = sum + a[i];
push local 2 // sum
push local 0 // base address of array a
push local 1 // i
add // calculate a[i] address
pop pointer 1 // set THAT to a[i]
push that 0 // get value at a[i]
add // sum + a[i]
pop local 2 // update sum
// let i = i + 1;
push local 1
push constant 1
add
pop local 1
goto WHILE_2
label END_WHILE_2
// do Output.printInt(sum);
push local 2
call Output.printInt 1
pop temp 0 // Discard return value
// return;
push constant 0 // Return void
return
Analyze this VM code. What Jack code could have produced it?
function Counter.new 0
push constant 1
call Memory.alloc 1
pop pointer 0
push constant 0
pop this 0
push pointer 0
return
function Counter.increment 0
push argument 0
pop pointer 0
push this 0
push constant 1
add
pop this 0
push constant 0
return
function Counter.getValue 0
push argument 0
pop pointer 0
push this 0
return
This VM code represents a simple Counter class in Jack with the following structure:
class Counter {
field int count;
/** Creates a new Counter with initial count 0 */
constructor Counter new() {
let count = 0;
return this;
}
/** Increments the counter by 1 */
method void increment() {
let count = count + 1;
return;
}
/** Returns the current count */
method int getValue() {
return count;
}
}
let x = 2 + 3 * 4 - 8 / 2;
In Jack, expressions are evaluated strictly left-to-right without operator precedence:
2 + 3
= 5
5 * 4
= 20
20 - 8
= 12
12 / 2
= 6
Therefore, x
equals 6, not 10 as it would be in languages with standard operator precedence.
What is the difference between these two VM code snippets?
// Snippet 1
push local 0 // object reference
push constant 5
call Point.move 2
pop temp 0
// Snippet 2
push constant 10
call Math.abs 1
pop local 1
Snippet 1 is a method call where:
The first argument (local 0
) is the object reference (implicit this
)
Total argument count includes this object reference
Translates to Jack: do point.move(5);
where point
is stored in local 0
Snippet 2 is a function call where:
No object reference is pushed
Arguments are only the explicit parameters
Translates to Jack: let x = Math.abs(10);
where x
is stored in local 1
The key difference: method calls always include an implicit object reference as their first argument.
What is wrong with this Jack code? How would you fix and implement it?
class Vector {
field Array data;
field int size;
constructor Vector new(int length) {
let size = length;
let data = Array.new(size);
return;
}
}
There are two issues with this code:
The constructor doesn't return this
, which is required in Jack
No initialization of the array elements
Corrected code:
class Vector {
field Array data;
field int size;
constructor Vector new(int length) {
var int i;
let size = length;
let data = Array.new(size);
// Initialize array elements to 0
let i = 0;
while (i < size) {
let data[i] = 0;
let i = i + 1;
}
return this; // Return this object
}
}
What is the Jack programming language?
Jack is a high-level, object-oriented programming language with Java-like syntax used in the Nand to Tetris course. It features classes, methods, basic data types (int, boolean, char), arrays, and simple control structures. Jack code is compiled to VM code before being translated to assembly language.
What is the VM (Virtual Machine) in the context of the Jack platform?
The VM is a stack-based intermediate language that serves as a bridge between the high-level Jack language and the low-level assembly language. It abstracts the hardware details and provides a set of commands for arithmetic operations, memory access, program flow control, and function calling.
What are the main memory segments in the VM architecture?
The VM architecture includes eight memory segments:
local: for function local variables
argument: for function arguments
this: for object fields (instance variables)
that: for array elements
constant: for constant values (read-only)
static: for static variables (class level)
pointer: for manipulating the 'this' and 'that' segments
temp: for temporary variables
What is the VM's stack and how is it used
The VM uses a stack-based architecture where operations pop operands from the stack and push results back onto it. All arithmetic and logical operations work exclusively with values on the stack. The stack is also used to pass arguments during function calls and to store return values.
What are the four categories of VM commands?
The four categories of VM commands are:
Arithmetic/Logical: add, sub, neg, eq, gt, lt, and, or, not
Memory Access: push, pop
Program Flow: label, goto, if-goto
Function Calling: function, call, return
Translate this Jack statement to VM code:
let sum = x + y;
(Assume x is a local variable at index 1, y is an argument at index 0, and sum is a local variable at index 2)
push local 1 // Push x onto the stack
push argument 0 // Push y onto the stack
add // Add x and y
pop local 2 // Store the result in sum
Translate this Jack if statement to VM code:
if (x > y) {
let max = x;
} else {
let max = y;
}
Translate this Jack if statement to VM code:
if (x > y) {
let max = x;
} else {
let max = y;
}
(Assume x is local 0, y is local 1, max is local 2)
push local 0 // Push x
push local 1 // Push y
gt // Compare: is x > y?
if-goto IF_TRUE
goto IF_FALSE
label IF_TRUE // If x > y
push local 0
pop local 2 // max = x
goto IF_END
label IF_FALSE // If x <= y
push local 1
pop local 2 // max = y
label IF_END
Translate this Jack method to VM code:
method int factorial(int n) {
if (n == 0) {
return 1;
}
return n * factorial(n-1);
}
(Assume this method is in a class called Math)
function Math.factorial 0
push argument 0 // Push n
push constant 0
eq // Compare n == 0
if-goto BASE_CASE
// Recursive case
push argument 0 // Push n
push argument 0 // Push n again
push constant 1
sub // Compute n-1
call Math.factorial 1 // Call factorial(n-1)
call Math.multiply 2 // Compute n * factorial(n-1)
return
label BASE_CASE
push constant 1 // Return 1 for base case
return
Translate this Jack object creation and method call to VM code:
let p = Point.new(10, 20);
let d = p.distance(5, 15);
// Object creation
push constant 10 // x coordinate
push constant 20 // y coordinate
call Point.new 2 // Call constructor with 2 arguments
pop local 0 // Store the new Point object in p
// Method call
push local 0 // Push object reference (this)
push constant 5 // x2 coordinate
push constant 15 // y2 coordinate
call Point.distance 3 // Call method with 3 args (including this)
pop local 1 // Store the return value in d
What VM code is generated for array access and assignment in this Jack code?
let arr[i] = arr[j] + 1;
// Computing arr[j]
push local 0 // Push base address of array
push local 2 // Push j
add // Compute address of arr[j]
pop pointer 1 // Set 'that' to point to arr[j]
push that 0 // Push the value of arr[j]
// Add 1
push constant 1
add // arr[j] + 1
// Store in arr[i]
push local 0 // Push base address of array
push local 1 // Push i
add // Compute address of arr[i]
pop pointer 1 // Set 'that' to point to arr[i]
pop that 0 // Store the value in arr[i]
How are object fields (instance variables) accessed in VM code?
Object fields are accessed through the 'this' segment. When a method is called, the object reference is passed as the first argument. The VM function uses 'pointer 0' to set the 'this' segment to point to the base address of the object, after which fields can be accessed as 'this 0', 'this 1', etc.
Explain the VM function calling convention.
The VM function calling convention is:
The caller pushes all arguments onto the stack (including the object reference for method calls)
The caller invokes the function with the 'call' command
The VM implementation saves the return address and other caller state
The called function allocates space for local variables
The function executes, accessing arguments via the 'argument' segment and locals via the 'local' segment
The function pushes its return value onto the stack (if any)
The 'return' command restores the caller's state and jumps to the return address
The caller continues execution, with the return value on top of the stack (if any)
How is array creation handled in the Jack-to-VM translation?
Array creation in Jack is translated to VM code that:
Pushes the desired size onto the stack
Calls the Memory.alloc function, which returns a base address
The base address is then stored in a variable to keep track of the array
For example, let arr = Array.new(5);
becomes:
push constant 5
call Memory.alloc 1 // Call with 1 argument
pop local 0 // Store the base address
What is the difference between the 'this' and 'that' segments in the VM?
The 'this' segment is used to access object fields (instance variables) during method execution, while the 'that' segment is primarily used for array access. Both are accessed indirectly through the 'pointer' segment: 'pointer 0' sets the base address for 'this', and 'pointer 1' sets the base address for 'that'.
How is a Jack constructor different from a regular method in the VM code?
In VM code, a Jack constructor:
Allocates memory for the object using Memory.alloc (size depends on the number of fields)
Sets 'pointer 0' to point to the newly allocated memory
Initializes the object's fields by storing values in 'this 0', 'this 1', etc.
Pushes the object's base address (this) onto the stack as the return value
Arithmetic/Boolean Commands in VM
These commands perform arithmetic and logical operations on the values at the top of the stack1 . The VM model features a 16-bit data type that can be used as an integer value, a boolean value, or a pointer2 . Boolean values are represented as 0 (for false) and -1 (for true)2 . The arithmetic and Boolean commands available are1 ...:
•
add: Pops the top two values from the stack, adds them, and pushes the result back onto the stack (x + y)1 .
•
sub: Pops the top two values, subtracts them, and pushes the result (x - y)1 .
•
neg: Pops the top value, negates it (arithmetic negation), and pushes the result (-y)1 .
•
eq: Pops the top two values, compares them for equality. Pushes true (=-1) if x = y, false (=0) otherwise1 ....
•
gt: Pops the top two values, compares them. Pushes true if x > y, false otherwise1 ....
•
lt: Pops the top two values, compares them. Pushes true if x < y, false otherwise1 ....
•
and: Pops the top two values, performs a bitwise AND operation, and pushes the result (x AND y)1 .
•
or: Pops the top two values, performs a bitwise OR operation, and pushes the result (x Or y)1 .
•
not: Pops the top value, performs a bitwise NOT operation, and pushes the result (Not y)1 .
Program Flow VM Commands
These commands control the flow of execution in the VM program3 .... They work together to allow for branching and looping6 . The program flow commands available are3 ...:
•
label: Declares a label at the current location in the code3 .... A label is a symbolic name that represents an address in the code7 .
•
goto: Unconditionally jumps to the specified label3 .... Execution continues from the location marked by the label7 .
•
if-goto: Pops the topmost stack element; if it's not zero, jumps to the specified label3 .... If the value is zero (false), execution continues to the next command in sequence7 .
To effect "if (x > n) goto loop"7 :
1.push x
2.push n
3.gt
4.if-goto loop
Memory Access Commands
These commands move data between the stack and the different memory segments3 ....
•push y: Pushes the value of y onto the stack. y can be a constant or a variable located in one of the memory segments (static, local, argument, this, that, pointer, temp)3 .... The stack pointer is then incremented9 .
•pop x: Pops the top value from the stack and stores it in x. x must be a variable located in one of the memory segments3 .... The stack pointer is then decremented9 ....
In simpler terms, think of the stack as a pile of plates10 ....
•Pushing is like adding a plate to the top of the pile3 ....
•Popping is like removing the top plate from the pile3 ....
The push command takes a value from a specified memory segment and places it on top of the stack3 .... The pop command removes the value from the top of the stack and places it in a specified memory segment
Jack library built in functions
Math: Provides basic mathematical operations3 .... This includes functions such as abs(), multiply(), divide(), min(), max(), and sqrt()5 .
•String: Implements the String type and string-related operations3 .... This includes functions such as new(), dispose(), length(), charAt(), setCharAt(), appendChar(), eraseLastChar(), intValue(), setInt(), backspace(), doubleQuote(), and newLine().
•Array: Implements the Array type and array-related operations
•Output: Handles text output to the screen3 .... Includes functions such as moveCursor(), printChar(), printString(), printInt(), println(), and backSpace().
•Screen: Handles graphic output to the screen. Includes functions such as clearScreen(), setColor(), drawPixel(), drawLine(), and drawCircle(). The drawPixel(x, y) function writes a predetermined value to the screen location corresponding to screen location (x,y).
•Keyboard: Handles user input from the keyboard3 .... Includes functions such as keyPressed(), readChar(), readLine(), and readInt(). The keyPressed() function depends on the specifics of the keyboard interface, and returns the ASCII value of the key if a key is presently pressed on the keyboard .
•Memory: Handles memory operations.... Includes functions such as peek(), poke(), alloc(), and deAlloc() . The functions peek() and poke() allow for "exotic casting" in Jack, creating a Jack-level proxy of the RAM.
•Sys: Provides some execution-related service. Includes functions such as halt(), error(), and wait()
what does this jack program do?
class Main {
function void main() {
var int a, b, sum;
let a = 10;
let b = 20;
let sum = a + b;
do Output.printInt(sum);
do Output.println();
return;
}
}
heres the vm: function Main.main 0
push constant 10
pop local 0 // a = 10
push constant 20
pop local 1 // b = 20
push local 0
push local 1
add // a + b
pop local 2 // sum = a + b
push local 2
call Output.printInt 1 // print sum
pop temp 0
push constant 0
call Output.println 1 // new line
pop temp 0
push constant 0
return
This Jack program defines a simple Main
class where two numbers are added, and the result is printed.
what does this code do?
class Countdown {
function void countDown() {
var int i;
let i = 10;
while (i > 0) {
do Output.printInt(i);
do Output.println();
let i = i - 1;
}
return;
}
function void main() {
do countDown();
return;
}
}
function Countdown.countDown 1
push constant 10
pop local 0 // i = 10
label LOOP_START
push local 0
push constant 0
gt // Check if i > 0
not
if-goto LOOP_END // If false, jump to the end of the loop
push local 0
call Output.printInt 1
pop temp 0
push constant 0
call Output.println 1
pop temp 0
push local 0
push constant 1
sub // i - 1
pop local 0 // update i
goto LOOP_START
label LOOP_END
push constant 0
return
function Countdown.main 0
call Countdown.countDown 0
pop temp 0
push constant 0
return
This example uses a while
loop to count down from 10, printing each value.
what does this program do: class ConditionalDemo {
function void test() {
var int a, b, max;
let a = 15;
let b = 10;
if (a > b) {
let max = a;
} else {
let max = b;
}
do Output.printInt(max);
do Output.println();
return;
}
function void main() {
do test();
return;
}
}
function ConditionalDemo.test 1
push constant 15
pop local 0 // a = 15
push constant 10
pop local 1 // b = 10
push local 0
push local 1
gt // if (a > b)
if-goto IF_TRUE
goto IF_FALSE
label IF_TRUE
push local 0
pop local 2 // max = a
goto IF_END
label IF_FALSE
push local 1
pop local 2 // max = b
label IF_END
push local 2
call Output.printInt 1
pop temp 0
push constant 0
call Output.println 1
pop temp 0
push constant 0
return
function ConditionalDemo.main 0
call ConditionalDemo.test 0
pop temp 0
push constant 0
return
This program shows an if-else
structure. It picks the maximum of two variables, then prints the result.
what does this code do?
class Factorial {
function int fact(int n) {
if (n <= 1) {
return 1;
} else {
return n * fact(n - 1);
}
}
function void main() {
var int result;
let result = fact(5);
do Output.printInt(result);
do Output.println();
return;
}
}
// Function: Factorial.fact
// Uses argument 0 for parameter n.
function Factorial.fact 0
// Check: if (n > 1) ? (if true: recursive case)
push argument 0 // push n
push constant 1
gt // Compute (n > 1) -> if true, result is -1 (true), otherwise 0 (false)
if-goto RECURSIVE // if n > 1, go to recursive case
// Base case: n <= 1, return 1
push constant 1
return
label RECURSIVE
// Begin recursive case: return n * fact(n - 1)
push argument 0 // push n (to be used for multiplication later)
push argument 0
push constant 1
sub // compute n - 1
call Factorial.fact 1 // recursive call; one argument (n-1)
mul // multiply: n * fact(n-1)
return
// Function: Factorial.main
function Factorial.main 0
push constant 5
call Factorial.fact 1
pop local 0 // store result in local variable 0
push local 0
call Output.printInt 1
pop temp 0
push constant 0
call Output.println 1
pop temp 0
push constant 0
return
This class defines a recursive fact
function that calculates the factorial of a number. For any input number n, if n is less than or equal to 1 the function returns 1; otherwise, it returns n times fact(n-1)
.
what does this code do?
class ArraySum {
function int sumArray(int[] a, int n) {
var int i, sum;
let i = 0;
let sum = 0;
while (i < n) {
let sum = sum + a[i];
let i = i + 1;
}
return sum;
}
function void main() {
var Array a;
var int result;
let a = Array.new(5);
let a[0] = 1;
let a[1] = 2;
let a[2] = 3;
let a[3] = 4;
let a[4] = 5;
let result = sumArray(a, 5);
do Output.printInt(result);
do Output.println();
return;
}
}
// Function: ArraySum.sumArray
// Uses arguments: 0 => array pointer (a), 1 => n (length)
function ArraySum.sumArray 2
push constant 0
pop local 0 // i = 0
push constant 0
pop local 1 // sum = 0
label WHILE_START
// Test: while (i < n)
push local 0
push argument 1
lt // computes i < n
not // reverse the result: if false (i >= n)
if-goto WHILE_END
// Compute: sum = sum + a[i]
push argument 0 // push base address of array a
push local 0 // push index i
add // compute effective address of a[i]
pop pointer 1 // THAT points to a[i]
push that 0 // push a[i] value
push local 1
add
pop local 1 // update sum
// Increment i = i + 1
push local 0
push constant 1
add
pop local 0
goto WHILE_START
label WHILE_END
push local 1 // push final sum to return value
return
This class has a function that sums the elements of an integer array. The function receives two parameters: the array a
and its length n
.
what does this program do?
class Multiply {
function int mul(int a, int b) {
var int i, product;
let product = 0;
let i = 0;
while (i < b) {
let product = product + a;
let i = i + 1;
}
return product;
}
function void main() {
var int result;
let result = mul(6, 7); // Expected result is 42
do Output.printInt(result);
do Output.println();
return;
}
}
// Function: Multiply.mul
// Uses arguments: 0 => a, 1 => b
function Multiply.mul 2
push constant 0
pop local 1 // product = 0
push constant 0
pop local 0 // i = 0
label LOOP_START
push local 0
push argument 1
lt // test if i < b
not
if-goto LOOP_END
// product = product + a
push local 1
push argument 0
add
pop local 1
// i = i + 1
push local 0
push constant 1
add
pop local 0
goto LOOP_START
label LOOP_END
push local 1 // return product
return
This program defines a function mul
that computes multiplication by adding one number a to itself b times. Then, in main
, it calculates 6 × 7 and prints the result.
what does this program do?
class FillArray {
function void fillArray() {
var int i;
let i = 0;
var Array a;
let a = Array.new(10);
while (i < 10) {
let a[i] = 123;
let i = i + 1;
}
return;
}
function void main() {
do fillArray();
return;
}
}
// Function: FillArray.fillArray
// Local variable 0: i; Local variable 1: holds array pointer (a)
function FillArray.fillArray 1
push constant 0
pop local 0 // i = 0
push constant 10
call Array.new 1
pop local 1 // local 1 now holds pointer to array a
label LOOP_START
push local 0
push constant 10
lt
not
if-goto LOOP_END
// Compute effective address: a + i
push local 1
push local 0
add
pop pointer 1 // THAT now points to a[i]
push constant 123
pop that 0 // a[i] = 123
// Increment i = i + 1
push local 0
push constant 1
add
pop local 0
goto LOOP_START
label LOOP_END
push constant 0
return
This example creates an array of size 10 and fills every entry with the value 123 using a while
loop.