When assembling Max.asm, the supplied assembler sets the first instance of the symbol address @OUTPUT_FIRST to 1010 (10 in decimal). And then the first instance of @OUTPUT_D to 1100 (12) and finally @INFINITE_LOOP to 1110 (14). I can't for the life of me think why this might be.
Running on Darwin, Mac OS X 10.9.3.
Can anyone help?
Does Max.asm contain labels? If so, what are they? What lines of assembly do the labels correspond to?
Hey ybakos, I've been sitting here reviewing your *Hint* and I am just not making a connection?
I see like mentioned that the following get translated:
@OUTPUT_FIRST = 0000 0000 0000 1010 (10)
@OUTPUT_D = 0000 0000 0000 1100 (12)
@INFINITE_LOOP = 0000 0000 0000 1110 (14)
And 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 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???
// 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,RAM,RAM)
D=M // D = first number
D=D-M // D = first number - second number
D;JGT // if D>0 (first is greater) goto output_first
D=M // D = second number
0;JMP // goto output_d
D=M // D = first number
M=D // M = D (greatest number)
0;JMP // infinite loop
It's not the source code line numbers that matter. The values for the symbols are the ROM address of the corresponding label: (OUTPUT_FIRST), etc.
Here's the listing file that my assembler generates for Max.asm.
The columns are:
Source line number,
ROM address for the instruction,
Instruction code (decimal for A-instructions, hexadecimal for C-instructions),
1: // This file is part of www.nand2tetris.org 2: // and the book "The Elements of Computing Systems" 3: // by Nisan and Schocken, MIT Press. 4: // File name: projects/06/max/Max.asm 5: 6: // Computes R2 = max(R0, R1) (R0,R1,R2 refer to RAM,RAM,RAM) 7: 8: 0 0 @R0 9: 1 FC10 D=M // D = first number 10: 2 1 @R1 11: 3 F4D0 D=D-M // D = first number - second number 12: 4 10 @OUTPUT_FIRST 13: 5 E301 D;JGT // if D>0 (first is greater) goto output_first 14: 6 1 @R1 15: 7 FC10 D=M // D = second number 16: 8 12 @OUTPUT_D 17: 9 EA87 0;JMP // goto output_d 18: 10 (OUTPUT_FIRST) 19: 10 0 @R0 20: 11 FC10 D=M // D = first number 21: 12 (OUTPUT_D) 22: 12 2 @R2 23: 13 E308 M=D // M = D (greatest number) 24: 14 (INFINITE_LOOP) 25: 14 14 @INFINITE_LOOP 26: 15 EA87 0;JMP // infinite loopNotice that A-instructions and C-instructions each use 1 word of ROM memory, but Labels do not use any ROM.
Your Pass One code needs to keep track of how much ROM is required so that it can assign the correct ROM address to the labels it adds to the symbol table.
@cadet1620 (Mark), I saw before how Labels (ex. "(Label)") were not being assigned a value directly per say during translation of the Assembler, but I am still not grasping the addressing for the @sometext commands.
Assuming your columns are actually:
Source Line Number,
ROM Address for the Instruction,
Source Code Line
I am not at all understanding why your values are going 0, FC10, 1, F4D0, 10, etc. (I get the R0, R1) for the ROM Addressing?
My current coding is going through a single pass, 1 line at a time, and correctly translates Add.asm and the various ***L.asm files, but the regular Max.asm, Pong.asm, and Rect.asm files are going wonky because I am not getting this ROM addressing thing.
Would it be possible for you to elaborate some more? I am just not seeing the light here. If it helps for any references, below is the corrected expected output based upon the provided Assembler:
As stated, second column is instruction's ROM address. Third column is instruction code.
Sorry about the mix of decimal and hexadecimal numbers. My assembler outputs hex for the C-instructions because I can read the bit patterns quickly from hex numbers (an occupational hazard :-) but I want to see the decimal ROM addresses since that's what the n2t tools display.
This is what it looks like in binary:
1: // This file is part of www.nand2tetris.org 2: // and the book "The Elements of Computing Systems" 3: // by Nisan and Schocken, MIT Press. 4: // File name: projects/06/max/Max.asm 5: 6: // Computes R2 = max(R0, R1) (R0,R1,R2 refer to RAM,RAM,RAM) 7: 8: 0000000000000000 0000000000000000 @R0 9: 0000000000000001 1111110000010000 D=M // D = first number 10: 0000000000000010 0000000000000001 @R1 11: 0000000000000011 1111010011010000 D=D-M // D = first number - second number 12: 0000000000000100 0000000000001010 @OUTPUT_FIRST 13: 0000000000000101 1110001100000001 D;JGT // if D>0 (first is greater) goto output_first 14: 0000000000000110 0000000000000001 @R1 15: 0000000000000111 1111110000010000 D=M // D = second number 16: 0000000000001000 0000000000001100 @OUTPUT_D 17: 0000000000001001 1110101010000111 0;JMP // goto output_d 18: 0000000000001010 (OUTPUT_FIRST) 19: 0000000000001010 0000000000000000 @R0 20: 0000000000001011 1111110000010000 D=M // D = first number 21: 0000000000001100 (OUTPUT_D) 22: 0000000000001100 0000000000000010 @R2 23: 0000000000001101 1110001100001000 M=D // M = D (greatest number) 24: 0000000000001110 (INFINITE_LOOP) 25: 0000000000001110 0000000000001110 @INFINITE_LOOP 26: 0000000000001111 1110101010000111 0;JMP // infinite loopYou can see in the third column the instructions in the Max.hack file.
Look at the second column for lines 18, 21, and 24. You can see the binary ROM address for the labels.
These are the same values that the symbols get as their instruction code when they are use in A-instructions.
In reply to this post by AnalyticLunatic
You are creating a two-pass assembler. The job of the first pass is to find the correct values for the labels. For this you'll go through each instruction and see what would be it's address. And when you see a label instruction, you'll have to remember somewhere (e.g. in a map or dictionary) the label and the corresponding address.
In HACK machine language, each instruction has the same size: 1 word. So it's easy to find the addresses: just count the instructions, starting from 0, and skipping comments, empty lines and labels. So for max.asm, we'll have the following:
OUTPUT_FIRST = 10
OUTPUT_D = 12
INFINITE_LOOP = 14
In the next pass, the assembler will use these values to generate instructions like @INFINITE_LOOP, which would be equivalent to @14.
One thing that might be a bit confusing is, that there is ROM, which contains the program, and there is RAM, which contains the data and they both have addresses, starting from 0. The CPU addresses the ROM trough the Program Counter (PC) register. When it needs to make a jump, it assumes that the jump address (the address of the instruction in the ROM) is the value of the A register. So it moves the value of A (e.g. 14) to the PC (that is, PC=14) and the next instruction that it will execute is the one at address 14 (which is 0;JMP).
On the other hand, the CPU addresses the RAM through C instructions, which reference M, such as M=D or D=M or M=M+1, etc. The A register again contains the address of the memory, but this time in RAM.
|Free forum by Nabble||Edit this page|