In the previous two units we talked about working with registers and
memory, branching, variables, iteration.
And what remains to be done in order to complete our survey of Hack
programming is talk about how we handle something called pointers.
And how we write programs that manipulate our input and output devices.
So, that's what we'll do in the current unit.
Let us begin with pointers.
And as usual I would like to start with an example, in which pointers come to play.
In particular, I want you to consider this very simple piece of code,
that many of you have written, at least those of you who took
programming courses before Nand to Tetris.
So in this code segment I manipulate an array called arr.
I assume that this array has been declared and initialized at some point.
And now I write a piece of code that sets the first
n entries of this array to the value -1.
If you write with a regular high level language,
it's very easy to write such a statement, such a for statement.
And as you know by now,
when you have to bring it down to the level of machine language,
you have to work much harder to deliver the required functionality.
So how do we do it?
Well one thing that you have to realize, and in fact,
you realize it only when you set out to write the compiler,
is that the notion of arrays gets lost in the translation, so to speak.
So when the assembler has completed to translate this piece of code from,
let's say java or python, into machine language,
the machine language no longer recognizes the array abstraction.
And as far as the machine language is concerned, the array is just as
segment in memory, of which we know the base address of this segment and
the length of the array that the programmer has decided to declare.
So if we assume that the array starts in address 100,
and that we want to do something to the first ten entries of this array,
this is how it's going to look like in the data memory on
which this program will end up executing.
We start with two variables.
One of them holds the base address of the array.
And the other one is the number of entries that we want to manipulate.
And what we would like to see is that at the end of the execution of this program,
we would like to see the first ten entries of this array set to -1.
This is the goal.
That's what we want to do.
And the question is, of course, how do we actually do it?
All right, so let's start working on writing this particular program.
The beginning of the program is going to setup these variables that we just
discussed.
So we assign the number 100 to arr to
signify that the array, arr begins in
the memory register number 100.
And we do something similar with n.
We assign the number 10 to n.
We initialize i to 0.
Once again, don't forget we are trying to deliver the functionality of a for
loop that begins with i equals 0.
So we set i to 0.
And then we can start actually going through the loop so to speak.
So once we do these three variable declarations and
assignments, we have this setting arr, n and
i allocated to memory registers 16, 17 and 18.
And we are ready to begin the actual processing.
All right, so here is the actual processing.
The first segment of the loop, and by the way,
we realize the for loop using a machine language-oriented
loop which begins with a label declaration called loop.
And the first thing that we do is translate the termination
condition into machine language.
So what used to be if i equals n go to end which is the end
of the processing because once i.
What is i?
I begins with 0 and goes through 1, 2, 3.
When it gets to 10 in our example we want to jump to n.
So we have six Hack instructions that actually perform the semantics.
And then we come to the heart of this loop in which we actually assign the number -1,
which is meaningless by the way, we just used as an example.
We assign -1 to the current entry of the array.
How do we do it?
Well, let us begin with a comment.
As you see what we are doing is we are computing the value
of arr plus i which is the value of the base address of
this array plus the current value of the index.
Now if the index begins with zero then the first entry that
we're going to operate on is RAM 100.
Because arr is 100.
And then i would become 1 so we'll operate on RAM 101.
And then, i becomes 2 we'll operate on RAM 102 and so on, and so forth.
How do we do it?
Well, we have to add up arr and i.
And that's exactly what we do in the first four instructions.
We set et arr, we address the variable called arr,
we put the value of this variable in d, then we say @i, we address the variable i.
We add up d plus m and we put the result in the a register.
Now, this is something which should be new to you.
Because it's the first time that we actually use this capability of
the language to assign something directly to a, using an arithmetic operation, okay?
Now, what will happen when we do it?
Well, d plus m now store an address.
So this address is assigned to a and by the time we say m equals
-1 the register that will be effected is the register that a addresses.
Now if we do this within loop that runs 10 times or
10,000 times in each iteration the a register will acquire one more address.
And we're going to operate on a different register in the memory.
And that's exactly what we want to do.
So, after we run so many iterations,
we'll get the desired effect.
And as usual we recommend that you stop the video and
convince yourself that this is actually Working as advertised.
So variables that store memory addresses like arr and
i are called pointers, in any language, not only in hack.
And, in hack, the typical logic is as follows.
Whenever we have to access memory using a pointer
we need some instructions like A equals something,
something that come from some memory register.
So the typical semantic is set the address register to
the value of some memory register in which I do some pointer
arithmetic to compute the address on which I want to operate.
So this, in a nutshell,
is how we do pointer processing in the heck machine language.