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 type Array and name arr.

  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 in THAT, we simply push arr then push index, and add to get arr + 2.

  • Then the THAT pointer will be aligned with the address we want to manipulate.

  • Notice that:

    1. We use only THAT 0, we don't use other entries from THAT segment.
    2. 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.

  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:

  1. 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 of b[j]:

  1. We pop the topmost value onto pointer 1, which is b[i] in this example. Once is done, we are going to get the following state:

  1. Now that That 0 is aligned with b[j], we push the value in b[j] and pop it into temp 0. This is the picture of the VM segments after the process:

  1. Because we have safely saved the value of b[i], we can take the address of a[i] and pop it onto pointer 1
  2. We finally push temp 0 onto the stack and pop it onto that 0, which is on the address of a[i]:

  The general solution for generating array access code is as below:

![[Pasted image 20240507234141.png]]