7.5.内存段的实现

\(7.5.\)Memory Segment implementation

1.local implementation

  The local segment can be placed anywhere we want in the host RAM, for we just need to remember the base address of the block.

  • We place the base address of the local segment in a pointer called LCL.
  • LCL will refer to RAM 1.

  Then we can push or pop a value easily. Say we want to accomplish pop local 2:

  We can do this by putting the stack-top value into RAM[1015].

  • How do we know which RAM to add to? We get it by base addr + index

  This process can be translated into this VM code:

1
2
3
4
5
6
//get the place to be added
addr = addr + index
//get the value, and put it into correct place
sp--
*addr = *sp
// D = *sp, *addr = D

  Notice that 5 is still in RAM[257], it hasn't been removed. It's common to have these wasted data in the stack, and it's not big deal, for the pointer indicates exactly which part of the stack are in play, not the data.

2.argument,this,that implementation

  • When translating the high-level code of some method into VM code:

    • Maps the method's local and argument variables onto the local and argument segments
    • Maps the object fields and the array entries that the method is currently processing onto the this and that segments

  The process of argument, this and that is nearly the same as local:

  The process can be translated into this VM code:

1
2
3
4
5
6
7
8
9
//push
addr = segmentPointer + index
*sp = *addr
sp++

//pop
addr = segmentPointer + index
sp--
*addr = *sp

3.Constant

  • When the compiler translates the high-level code of some method into VM,

    • it translates high-level operations involving constant into VM operations involving the constant segment.
  • When we implement constant, we simply supply the specified constant.

  • Since we won't store things where a constant resides, there's no pop in constant.

  • The constant segment is a truly virtual segment. So whenever we see a push constant i command, we simply supply the specified constant i.

4.Static

  • When translating the high-level code of some method into VM code, the compiler:

    • Maps the static variables that the method sees onto the static segment.
  • The static variables should be seen by all the methods in a program.   To complement this, we store the variables in a "global space":

  • Have the VM translator translate each VM reference static i(in file Foo.vm)into an assembly reference Foo.i.

    • Foo is the name of the file, and i is the index of VM command.
  • Following assembly, the Hack assembler will map these references onto RAM[16],RAM[17],RAM[18], ...

  For example, the statement pop static 5 can be translated into:

1
2
3
4
5
6
@Foo.5
M = D
//the register stores this data

@Foo.2
M = D
* The entries of static segment will end up being mapped onto RAM[16], RAM[17], ... , in the order in which they appear in the program (not their names!!!).

Alt text

Static variables are stored in a section of memory called the static data segment, which is allocated when the program is loaded and has fixed memory addresses. When we want to retrieve the value of a static variable, we need to read the value stored at the memory location where the static variable is stored, rather than directly accessing the value of the static variable itself. This is why we need to use D=M instead of D=A to get a static value.

5.Temp

  When the compiler translates the Jack program into VM code, it sometimes has to use temporary variables.

  • We let the 8 place segment called temp to contain and serve these variables when needed.
  • temp is going to be a fixed 8-place memory segment.
  • The variables will be mapped on RAM locations 5 to 12.

6.Pointer

  • When translating a high-level method code into VM code,the compiler:

    • Has to remember the base addresses of this, which represents the current object, and that, which represents the current array of method be processing.
    • Generates code that keeps track of the base addresses of the this and that segments using the pointer segment.
  • pointer is a fixed memory segment. It has only two entries, 0 and 1.

    • So we can only push and pop 0 and 1
  • Accessing pointer 0 should result in accessing THIS.

  • Accessing pointer 1 should result in accessing THAT.