|
12
|
I am not sure I understand how to deal with the following spec: "Each static variable j in file Xxx.vm is translated into the assembly symbol Xxx.j. In the subsequent assemblyprocess,
these symbolic variables will be allocated RAM space by the Hack assembler."
For example, in the StaticTest.vm exercise, I used variable 'StaticTest.8' for the 'push static 8' vm command. The CPU emulator assigns it to RAM(16) and not RAM(24) as one might naively assumes.
Please clarify the rationale behind this spec.
Thanks
|
Administrator
|
yoav wrote
I am not sure I understand how to deal with the following spec:
"Each static variable j in file Xxx.vm is translated into the
assembly symbol Xxx.j. In the subsequent assembly process,
these symbolic variables will be allocated RAM space by the
Hack assembler."
For example, in the StaticTest.vm exercise, I used variable 'StaticTest.8'
for the 'push static 8' vm command. The CPU emulator assigns it to RAM(16)
and not RAM(24) as one might naively assumes.
Please clarify the rationale behind this spec.
Thanks
Your translation is correct.
StaticTest.8 is a symbol name, handled the same as abc.xyz, no arithmetic is implied. Remember that the assembler assigns RAM addresses to unknwn symbol names sequentially starting at 16.
Eventually you will be translating multiple VM files into a single ASM so you will have static variables from multiple classes, and every one needs to end up with a unique symbol name.
--Mark
|
|
yoav, as Mark asserts above, your thinking is correct. However, the example you've created is contrived. In valid VM instructions, which will be generated by a proper compiler, you can assume that StaticTest.0 - 7 would be defined before StaticTest.8.
Furthermore, a variable called StaticTest.8 doesn't necessarily translate to "static 8". But this is something that will be revealed as you progress with the VM and compiler. Good luck!
|
Administrator
|
The statics won't necessarily be in numeric order, depending on how you write your translator. My translator defines the numeric ID in the order the static variable declarations appear, but the first appearance of the symbol in the assembly output is the first time the static variable is used.
My normal coding style initializes the statics in the order they are declared so the IDs are usually in numeric order, but not guaranteed.
--Mark
|
|
It is a bit confusing because when you run the StaticTest.vm, it pops
static 8 in RAM[24]
static 3 in RAM[19]
static 1 in RAM[17]
it should be in order of appearance
static 8 in RAM[16]
static 3 in RAM[17]
static 1 in RAM[18]
An error in the VM Emulator?
It got me going for 30min.
Koen
|
Administrator
|
I don't see this as an error in the VM emulator. Since the VM specification doesn't define in what order VM files in a directory are to be processed, there is no guarantee where any particular static variable will be located.
Also, the assembler doesn't require that undefined symbols be assigned addresses in source code order. Another valid approach would be to add all symbols to the symbol table during pass 1. Then between passes 1 and 2, traverse the symbol table, perhaps in alphabetical order, and assign addresses to any symbols that do not already have addresses. Then pass 2 doesn't need to do anything special for symbols; they already all have addresses.
--Mark
|
|
I don't mean error as an error in the software. I mean it as a bad example. What happens in the VME does not seam to respect what we've learned about the Assembler.
No disrespect
Koen
|
|
I assume the names of the variables do not have to be "xxx.i" where "xxx" is the name of the source vm file. In my implementation I use "Vn.i" where "n" is a sequential number I increment for each vm file compiled in a single run.
So static variables for the first file in the run will be "V1.8", "V1.3" etc. Those produced by the second file will be like "V2.3", "V2.2" etc.
Does anyone think this would cause trouble later on ?
Albert
|
|
Koen_Be3840 wrote
It is a bit confusing because when you run the StaticTest.vm, it pops
static 8 in RAM[24]
static 3 in RAM[19]
static 1 in RAM[17]
it should be in order of appearance
static 8 in RAM[16]
static 3 in RAM[17]
static 1 in RAM[18]
An error in the VM Emulator?
It got me going for 30min.
Koen
I'm glad to see I'm not the only one that was confused by this. What is being said in this thread is that the proposed implementation in the chapter (using Xxx.n) results in the three values static 8, 3, and 1, being assigned to RAM[16], RAM[17], and RAM[18] respectively. Your test, however, uses the numbers 8, 3, and 1 as an offset from RAM[16] and places them in RAM[24], RAM[19], and RAM[17] respectively.
In order to arrive at the correct test output I simply used RAM[16] as my base for static and used the numbers following static as an offset value and was able to output the same output as the test. However, this has meant that I haven't actually implemented the suggestion in the book. If I had implemented the solution the way the book suggest it, I would have arrived at the same result as the gentlemen in this thread. I would have three variables assigned to RAM[16], RAM[17], and RAM[18] and would fail the provided test.
I suppose what I want to know is how exactly did the VM Emulator implement static? Does it allocate a block of memory for the static variables of each .vm file and refer to that base address of that block?
|
Administrator
|
sgaweda wrote
In order to arrive at the correct test output I simply used RAM[16] as my base for static and used the numbers following static as an offset value and was able to output the same output as the test. However, this has meant that I haven't actually implemented the suggestion in the book.
If you implement "static n" as RAM[16+ n], then you will fail the 08/FunctionCalls/StaticsTest test. That test validates that Class1.vm's "static n" refers to a different RAM location than Class2.vm's "static n".
I suppose what I want to know is how exactly did the VM Emulator implement static? Does it allocate a block of memory for the static variables of each .vm file and refer to that base address of that block?
Something like that. You can download the Java source code for the VM Emulator and read it if you want to know exactly how it works :^)
I did a bit of experimenting with 08/FunctionCalls/StaticsTest, and it looks like this is what the VME is doing:
1) Let STATIC_BASE = 16
2) Read a VM file, keep track of the largest static index used (MAX_INDEX)
3) All "static n" references in this VM file refer to RAM[STATIC_BASE+ n].
4) Let STATIC_BASE = STATIC_BASE + MAX_INDEX + 1
Repeat 2-4 for remaining VM files in the directory.
I assume the VME does this so that it can reuse its memory segment UI code for the static segment. It is indeed unfortunate that this ends up implying the use of RAM[16+ n] when reverse engineering with StaticTestVME.tst.
I'll need to think a bit about the best way to have StaticTest.tst check that "static n" is not implemented as RAM[16+ n].
--Mark
|
|
cadet1620 wrote
Something like that. You can download the Java source code for the VM Emulator and read it if you want to know exactly how it works :^)
I did a bit of experimenting with 08/FunctionCalls/StaticsTest, and it looks like this is what the VME is doing:
1) Let STATIC_BASE = 16
2) Read a VM file, keep track of the largest static index used (MAX_INDEX)
3) All "static n" references in this VM file refer to RAM[STATIC_BASE+n].
4) Let STATIC_BASE = STATIC_BASE + MAX_INDEX + 1
Repeat 2-4 for remaining VM files in the directory.
I assume the VME does this so that it can reuse its memory segment UI code for the static segment. It is indeed unfortunate that this ends up implying the use of RAM[16+n] when reverse engineering with StaticTestVME.tst.
I'll need to think a bit about the best way to have StaticTest.tst check that "static n" is not implemented as RAM[16+n].
--Mark
Thank you for the speedy response. I've decided to go with similar implementation to how the vme executes the code, but I'm still confused about how this relates to the suggested implementation in the book. The book suggests labeling each static variable using a naming convention of Xxx.j where Xxx is the name of the vm file and j is the index given for the static variable. I understand the compiler won't ever give a situation where it's defining the 8th variable without defining the 7th variable, but to implement the changes required to satisfy StackTest.tst I still have to deviate heavily from the proposed implementation in the book.
If the specific test in StackTest.tst isn't ever going to occur once we've written our compiler, why are we testing for it? As a corollary, if the vme implements this solution differently, why doesn't the book suggest that implementation instead of the Xxx.j approach to solving this particular resource allocation? I'm having trouble understanding what use case this particular test satisfies.
|
Administrator
|
sgaweda wrote
... to implement the changes required to satisfy StackTest.tst I still have to deviate heavily from the proposed implementation in the book.
I don't understand what doesn't satisfy StackTest.txt when you use symbolic names for the static variables. StaticTest.tst is not looking for anything in RAM locations 16+1, 16+3 or 16+8. It should not care where in RAM the static variables are stored. As long as "push static n" retrieves the same value as was written by "pop static n", the computed value left on the stack will be correct and the test will pass.
If you would like, I can send you the StaticTest.asm that my VM translator generates that passes the test, using symbolic names.
... why doesn't the book suggest that implementation [the VME's behavior] instead of the Xxx.j approach to solving this particular resource allocation? I'm having trouble understanding what use case this particular test satisfies.
To allocate a static segment the way the VME does requires that your VM translator must keep track of the maximum segment index used as it translates each VM file and manage the static segment base address as it processes sequential VM files.
The code to just write ClassName. n is simpler. (It also matches how the VM translator that generated 06/Pong.asm handles static variables.)
--Mark
|
|
I understand now! I was under the impression that I needed to effect the same result as the vme and didn't realize that the test doesn't even check to see where the variables were stored, just that the final output is correct. I've already implemented it with the same logic as the vme, but will likely rewrite it now that I understand the proposed implementation still passes the test. Looking forward to tackling project 8 now as well.
|
|
Mark, I'll take you up on that offer to send me your StaticTest.asm I'd really like to see how my generated code compares to yours. How can I send you my email address?
|
Administrator
|
sgaweda wrote
How can I send you my email address?
You can send text email directly to forum posters using the "More->Reply to Author" dropdown on any post.
--Mark
|
|
I'm glad it's not just me that has found what appears to be a contradiction between the book and the VMEmulator test script StaticTestVME.tst...
Lozminda
|
Administrator
|
The key is that the specification only dictates what the required behavior is. There are many ways to achieve that behavior, and by definition if they accomplish that then they are a correct implementation.
The text provides hints and suggestions on possible ways of going about things, but they are not requirements. Naturally, people unfamiliar with the material can have a hard time distinguishing the sometimes subtle line between specs and suggestions. If I recall, the authors basically lay that out pretty early on, but then they make a very common mistake of educators all over the place and assume that saying it once is all that is needed -- that seldom proves to be the case.
|
|
Yep, I'm running into the same issues with the "thinking"....(again)
|
|
The CPUEmulator (running my .asm file) stores the statics in the different order (I've followed what the book has said) to the VMEmulator (mine starts at R[16] the VMEmulator starts at R[19] and works backwards - ish).
As a consequence I end up with different statics on the stack at the end. I can't work out whether this is intended behaviour or not. Everything else works fine, different Classes store statics in a different places, (but in the right range R[16] onwards) but not in the same way.
Any help much appreciated, i'm not sure I’ve understood all the previous dialogue, but then it's getting a bit late for me.
A small ps..
I'd guess this might be another of those areas where the book maybe isn't as clear as the authors think it is; as completely different people from every corner of the world (i'd imagine) at completely different times seem to be running into the same trouble.
And before I get blasted off the planet, I think the course is brilliant however nor do I think the above observation is unfair either..
|
Administrator
|
While I can't speak with any authority about code I haven't seen, you need to keep in mind that the addresses that are assigned to static variables depends on the exact order in which those variables appear in the assembly language code and that, in turn, depends on the order in which the VM Translator processes the .vm files.
Also, if you are using the built-in OS functions instead of actual VM code for them, then be aware that some of the OS functions contain static variables. If you use the VM code, those variables will be handled just like any other static variables. But if you use the built-in OS functions in the VM Emulator, those variables may be handled internally within the Java implementations of those functions.
|
12
|