| 
                        
                     | 
                    
                        
		
		
		
		
		
			
				| 
					
	
	
	
	
				 | 
				
					
	
	 
		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?
 
	
	
	
	 
				 | 
			 
		 
	 
	
		
		
			
				| 
					
	 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
	
	
	
	  
				 | 
			 
		 
	 
	
		
		
			
				| 
					
	
	
	
	
				 | 
				
					
	
	
		@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.
	
	
	
	  
				 | 
			 
		 
	 
	
		
		
			
				| 
					
	
	
	
	
				 | 
				
					
	
	 
		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... 
	
	
	
	 
				 | 
			 
		 
	 
	
		
		
			
				| 
					
	 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
	
	
	
	 
				 | 
			 
		 
	 
	
		
		
			
				| 
					
	
	
	
	
				 | 
				
					
	
	 
		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). 
	
	
	
	 
				 | 
			 
		 
	 
	
		
	 
	 
                        
                     |