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