10.8.对数组的处理
\(10.8.\)Handling Array
1.Array construction
Assume that the high-level programmer writes
var Array arr
.
- In response to this, the compiler will only allocate a
local
variable to represent the array and initialize this variable to 0. - This statement generates no code. The compiler will
get a variable called
loca1 0
, its typeArray
and namearr
.
When we construct this array by calling the subroutine of the
Array
class: let arr = Array.new(5)
.
- The compiler and OS will magically allocate sufficient space in the heap to represent the array.
- The base address of the new allocated block is going to be stored in
local 0
, regardless of the address may be. - What we have here is a standard call to a Jack subroutine, which we already knew how to handle.
2.Array manipulation
\(a.\)THIS
and THAT
review
\(b.\)Generating code
Suppose we want to conduct arr[2] = 17
:
Since the base address of
arr
is stored inTHAT
, we simplypush arr
thenpush index
, andadd
to getarr + 2
.Then the
THAT
pointer will be aligned with the address we want to manipulate.Notice that:
- We use only
THAT 0
, we don't use other entries fromTHAT
segment. - The VM code you have operates in a completely symbolic logical world. It doesn't know where the array is located in RAM or which address we are manipulating. In this respect, it's a very safe code, for it cannot reach out of the VM world, because all the physical considerations are being implemented by the VM translator, and VM code itself is completely oblivious of the host platform. This is very important because we have numerous different computers, we don't know where this code is going to run, and we don't have the luxury of making any assumptions about the underlying hardware platform.
- We use only
What about arr[exp1] = exp2
? As above, we may write
the following code:
This seems make sense, but when we try to write
a[i] = b[j]
, there comes a crush:
To avoid this, we:
- First deal with the right hand side and left hand side separately.
Once we complete this, the stack is going to contain two
addresses: the address of
a[i]
and the address ofb[j]
:
- We
pop
the topmost value ontopointer 1
, which isb[i]
in this example. Once is done, we are going to get the following state:
- Now that
That 0
is aligned withb[j]
, wepush
the value inb[j]
andpop
it intotemp 0
. This is the picture of the VM segments after the process:
- Because we have safely saved the value of
b[i]
, we can take the address ofa[i]
andpop
it ontopointer 1
- We finally
push temp 0
onto the stack andpop
it ontothat 0
, which is on the address ofa[i]
:
The general solution for generating array access code is as below:
![[Pasted image 20240507234141.png]]