Bill Thackston wrote
So if I understand you correctly, good coding practice would be to avoid using both direct register addressing and user symbols in the same program.
Yes it is good practice not to mix RAM variables and absolute RAM addressing, but there are many cases when you need to do so. For example to address memory-mapped resources like the Screen and Keyboard, and to address objects that have been assigned a fixed location in memory.
The Hack assembler provides built-in symbols for the Screen and Keyboard, but has no facility to define new symbols for fixed resources. An example of such a resource is the heap which resides from 2048-16383 (dynamically allocated memory for the Jack OS--chapter 12) . A more comprehensive assembler would allow a way to set such symbols.
Assemblers are not generally intended for people to write large programs; they are a way to get exact sequences of machine instructions when you need to deal directly with the computer hardware or achieve specific goals like highest possible execution speed or fixed code execution time.
I'm attempting to add another layer of checking during the second pass. So in your example, "@16" would be identified and the first user symbol i would be assigned to 17, and so on.
When you get to writing your Jack compiler you will find that the direct RAM that the assembler can use via named variables is limited to 16-255, so it is a precious resource. You don't want to throw any of it away because there is an direct numeric reference to it. (There wil be lots of these because all characters in string constants will appear as their numeric code in an '@' statement.)
--Mark