Translation of Add operation

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

Translation of Add operation

asev98
I've some doubt about the translation of the add operation from VM language to Assembly language.
I would translate it like this, using R13 register:

@SP
D=A-1
@0
M=D
@SP
D=M
@SP
R13=A-1
@0
M=R13
@SP
A=M
D=D+A
@SP
M=D
@SP
D=A+1
@0
M=D

My questions is: did I use R13 properly? Did I update the SP in the right way?
Reply | Threaded
Open this post in threaded view
|

Re: Translation of Add operation

cadet1620
Administrator
R0 - R15 are "virtual registers". They are just alternate names for RAM locations 0 - 15. They are accessed just like any other RAM variable, using "@R13", for example. You can not use them in C-instructions.

"@0" and "@SP" are identical commands since the address of SP is 0, so a sequence like
    @0
    M=???
will change the SP value.


Because accessing RAM variables like SP and R13 take multiple instructions, you want to limit the number of times that you access RAM variables and do most of the work using only the A and D registers.

An efficient way to do the VM "add" command is:
  o  Load SP value into the A register so that M will reference values that are on the stack.
  o  Change the value of A (without using D or @) so that it points to various places on the stack so that you can read one of the stack values into the D register, change A again, and add D to the other value on the stack.
  o  Finally, decrement SP.

What this looks like in ASM:
        // [Comments assume push x; push y; add]
@SP
A=M-1   // A points to y value
D=M     // D = y
A=???   // change A to point to x value
???     // add y to x
@SP
???     // decrement stack pointer
--Mark
Reply | Threaded
Open this post in threaded view
|

Re: Translation of Add operation

asev98
@SP
A=M-1

Those lines put the value of SP-1 onto the A register or am I wrong?
Why do you decrement the SP at the end?
Reply | Threaded
Open this post in threaded view
|

Re: Translation of Add operation

cadet1620
Administrator
asev98 wrote
@SP
A=M-1

Those lines put the value of SP-1 onto the A register or am I wrong?
That is correct.  Note that it does not change the value of SP.
Why do you decrement the SP at the end?
Because the "add" operation combines the two arguments on the stack into a single result value on the stack, the stack will be one shorter than it was before the "add" operation.

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

Re: Translation of Add operation

asev98
This post was updated on .
Yes, I didn't think that those two lines don't change the value of SP.

A=???
???

I should replace ??? with
A=A-1
D=D+A

and to decrement SP
@SP
M=M-1

then

M=D

is this correct?
Reply | Threaded
Open this post in threaded view
|

Re: Translation of Add operation

cadet1620
Administrator
You need to add D to the value on the stack that the A register points to, not its address.

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

Re: Translation of Add operation

asev98
I think I don't understand,

@SP
A=M-1   // A points to y value
D=M     // D = y

why D=Y?
Isn't the value of Y in address M-1 and not in M?

I can't undestand how I can put a value in RAM[SP] too
Reply | Threaded
Open this post in threaded view
|

Re: Translation of Add operation

cadet1620
Administrator
Racall that the M "register" is not really a register; it is a data path in the CPU that reads or writes RAM[A], using the current value of the A register.

Given this state for the stack:
SP = 258
RAM[256] = x
RAM[257] = y
You need to replace RAM[256] with x+y, and decrement SP to remove the y value from the stack.

Here how the code works, slightly expanded for clarity:
@SP         // A = address of SP = 0
A=M         // A = RAM[A] = RAM[0] = value of SP = 258
A=A-1       // A = (value of SP)-1 = 257 = address of y
D=M         // D = RAM[A] = RAM[257] = value of y
The two A= commands in the above code can be combined into a single command since the ALU operation -1 comes after the RAM[A] memory read.  (Refer back to the CPU diagram 5.8 in chapter 5.)
A=M-1       // A = (RAM[A])-1 = (value of SP)-1 = 257 = address of y

asev98 wrote
I can't undestand how I can put a value in RAM[SP] too
You should already be doing this as part of the "push constant #" commands that come before the "add".
@SP         // A = address of SP = 0
A=M         // A = RAM[A] = RAM[0] = value of SP
M=D         // RAM[value of SP] = D
--Mark
Reply | Threaded
Open this post in threaded view
|

Re: Translation of Add operation

asev98
This post was updated on .
So the M war referring to the A before, I didn't understand it before, thank you a lot, you gave ma a big help.
Anyway I still don't understand how M works. Sometimes it stores a value, sometimes an address. How can I decide when it should do a certain thing?