Bootstrap Code vs. Initialization?

classic Classic list List threaded Threaded
2 messages Options
jrd
Reply | Threaded
Open this post in threaded view
|

Bootstrap Code vs. Initialization?

jrd
Apologies, if this has been answered elsewhere in the forums.  Couldn't seem to find related topic.

As described on p. 165, I've correctly implemented my writeInit function - which effects the machine language bootstrap code for:

SP = 256
call Sys.init

However, later on p. 171, there is the discussion of further Initialization, where the remaining virtual memory segments beyond SP need to be initialized.

- Should I, therefore, assume that as part of my writeInit routine, I should *also* set LCL, ARG, THIS, THAT to their default memory addresses (as generally used throughout the book - i.e., 300, 400, 3000, 3010)?

- Or, should I be initializing these additional virtual memory segments in a separate routine - other than in writeInit?

- Or, will the Nand2Tertris supplied .tst scripts handle those initializations for me?  (Doubt this, since I don't see that occurring in FibonacciElement or StaticTest, and Tip on p. 171/172 suggests otherwise "The last two programs assume that the startup code is already part of the VM implementation.")

Can you please clarify this for me?  Thx.

- JRD

Reply | Threaded
Open this post in threaded view
|

Re: Bootstrap Code vs. Initialization?

cadet1620
Administrator
jrd wrote
As described on p. 165, I've correctly implemented my writeInit function - which effects the machine language bootstrap code for:

SP = 256
call Sys.init
The above is correct bootstrap code.

The four pointers LCL, ARG, THIS and THAT will be set by properly functioning code before they are used.

LCL and ARG will be set when "call Sys.init" builds the stack frame. THIS and THAT are used by VM code generated by the Jack compiler. A properly working Jack compiler will write "pop pointer" commands before the "this" or "that" segment are referenced.

My professional experience says that it is always best to initialize pointers. I prefer to initialize them to a value that will cause an exception or system error if they are used before being set to a valid value.

In my VM translator I initialize them to -1, -2, -3 and -4. Setting them to different values can make it easier to track down where an uninitialized pointer came from. (And the code to set those values is nice and short. Assuming A==0, it's A=A+1 M=-A ...)

However, later on p. 171, there is the discussion of further Initialization, where the remaining virtual memory segments beyond SP need to be initialized.
This is talking about only the BasicLoop, FibonacciSeries and SimpleFunction tests.

Because these three tests run without bootstrap code, the .tst script must set all the pointers that will be used by the commands in the tests' .vm files.

SimpleFunction.tst, for example, does this:
set RAM[0] 317,         // SP
set RAM[1] 317,         // LCL
set RAM[2] 310,         // ARG
set RAM[3] 3000,        // THIS
set RAM[4] 4000,        // THAT
set RAM[310] 1234,      // ARG[0]
set RAM[311] 37,        // ARG[1]
set RAM[312] 1000,      // ARG[2]
set RAM[313] 305,       // ARG[3]
set RAM[314] 300,       // ARG[4]
set RAM[315] 3010,      // ARG[5]
set RAM[316] 4010,      // ARG[6]
This is setting the pointers and the stack to look like some function called
    SimpleFunction.test (1234, 37, 1000, 305, 300, 3010, 4010);

(Why it sets that up is a mystery since it only uses args 0 and 1. My guess is that the setup code was copied from some other more complicated test.)

--Mark