How are custom labels like @OUTPUT_FIRST values being decided?

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

How are custom labels like @OUTPUT_FIRST values being decided?

AnalyticLunatic
Can someone help me understand how/why the custom labels are being translated the way they are by the built-in Assembler?

I see on Max.asm that the following get translated as so:

@OUTPUT_FIRST = 0000 0000 0000 1010 (10)
@OUTPUT_D = 0000 0000 0000 1100 (12)
@INFINITE_LOOP = 0000 0000 0000 1110 (14)

And further below is the Max.asm file. No matter how I look through it (comments, no comments) I am not seeing how/why the 10/12/14 values are being chosen? At first I had set these 3 values hard-coded in a reference Dictionary in my code and it worked no problem for Max.asm file, but then on Rect.asm file the @INFINITE_LOOP was coming in as 0000 0000 0001 0111 (23) instead by the built-in Assembler???

Also, why is it that @R0, @R1, etc come through as (0) and (1) and so forth? I thought with the "R" value first it would basically be a custom label and thus start wherever the current counter (16 or higher) is?

Max.asm:

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/06/max/Max.asm

// Computes R2 = max(R0, R1)  (R0,R1,R2 refer to  RAM[0],RAM[1],RAM[2])

   @R0
   D=M              // D = first number
   @R1
   D=D-M            // D = first number - second number
   @OUTPUT_FIRST
   D;JGT            // if D>0 (first is greater) goto output_first
   @R1
   D=M              // D = second number
   @OUTPUT_D
   0;JMP            // goto output_d
(OUTPUT_FIRST)
   @R0            
   D=M              // D = first number
(OUTPUT_D)
   @R2
   M=D              // M[2] = D (greatest number)
(INFINITE_LOOP)
   @INFINITE_LOOP
   0;JMP            // infinite loop

Can someone explain this to me?
Reply | Threaded
Open this post in threaded view
|

Re: How are custom labels like @OUTPUT_FIRST values being decided?

cadet1620
Administrator
AnalyticLunatic wrote
Also, why is it that @R0, @R1, etc come through as (0) and (1) and so forth? I thought with the "R" value first it would basically be a custom label and thus start wherever the current counter (16 or higher) is?
R0-R15 are predefined  labels that refer to RAM addresses 0-15.  There are some other predefined values as well.  See 4.2.4 in the chapter 2 text.

See This response to your other post for info about the code labels.

--Mark
Reply | Threaded
Open this post in threaded view
|

Re: How are custom labels like @OUTPUT_FIRST values being decided?

AnalyticLunatic
@Mark, Thanks for the quick response. I now see about the pre-defined values (specifically R0-R15) in Chapter 4 for 4.2.4: http://nand2tetris.org/chapters/chapter%2004.pdf .

However I am still lost on the ROM addressing. I'll address in the other post.









Reply | Threaded
Open this post in threaded view
|

Re: How are custom labels like @OUTPUT_FIRST values being decided?

The_Larks
In reply to this post by AnalyticLunatic
I'm just doing this project now and have completed the symbol-less version.

RE: custom labels.

So, (OUTPUT_FIRST) (assuming code starts at Line 0), is actually on Line *10* of the pre-processed .asm file. So, any reference to @OUTPUT_FIRST really means "GOTO LINE 10", at which point the *next* line after (OUTPUT_FIRST) gets executed (in this case, @R0). After you have preprocessed this portion of the assembly, you would actually delete (OUTPUT_FIRST) entirely, shifting "@R0" up from Line 11, to Line 10. You'll notice at this point that (OUTPUT_D) is at Line 12. You would remove this line and "@R2 moves up into Line 12, so that any reference to @OUTPUT_D means literally "Goto Line 12, @R2". If you load this into the supplied Assembler, you can confirm all this for yourself.

You can figure out (INFINITE_LOOP) from here...
Reply | Threaded
Open this post in threaded view
|

Re: How are custom labels like @OUTPUT_FIRST values being decided?

cadet1620
Administrator
Don't think of label addresses as "line numbers". They are ROM addresses for the following CPU instruction.

During pass 1 initialize a romAddr variable to 0 and increment it every time you encounter a CPU instruction (A- or C-command). When you encounter a label, use romAddr as the label's address.

Algorithms that linearly process lists, deleting items from the list as they process it, are slow because simple lists are usually stored in a single block of memory and when you delete item i all the items i+1 to N need to be moved.

This isn't necessarily as bad as it sounds, because the actual list is a list of pointers to the string data, so the string data itself doesn't need to be moved.

--Mark
Reply | Threaded
Open this post in threaded view
|

Re: How are custom labels like @OUTPUT_FIRST values being decided?

The_Larks
Yes, I am totally aware that I botched the focal language; it was intentional. What I intended to do for implementing the assembler w/symbols was to simply store the code in a std::map. This gives me the API I need for a PC and guaranteed stability of the map container. Not just that, the PC (or map), would automatically  maintain the proper order - by design - with insertion and deletion.

I was walking the OP through the example - linearly - so that he could get an idea of how the "OUTPUT_FIRST values [are] being decided". I realize that what I was referring to as a line#, is actually a ROM address (register).