|
12
|
Apologies for resurrecting an old thread but this static part really has frusturated me to no end.
The VM emulator allocates memory in a way that's really confusing, and it seems to contradict the book.
So the command "pop static 8" pops the value from the stack to the register 24. So, I assumed that it was using the address 16 as the base address, and "8" as the offset. (same thing with other commands) I quickly churned up something with this in mind, and the problem is, it actually passed the test. Although, later it dawned on me that my solution could not be correct, since I was using the register 16 to store the base address (which is also 16), which would make storing anything in the 16th register impossible, and I assume would cause great problems down the line.
I will attack this problem tomorrow with a clearer mind, but I feel like the VM emulator really misled me on this one. I assume I will have to scrap my whole solution and start from the scratch.
|
Administrator
|
You are making a very common mistake.
The command
pop static 8
does NOT say to store a value into RAM[24].
It says to store a value into index #8 in the current file's static memory segment.
The VM language (and VM emulator) works at the level of memory segments. It has zero awareness of how those memory segments are mapped onto a particular hardware architecture.
In the case of the static memory segments, we have the following required behavior:
1) Each VM file has it's own static memory segment.
2) That VM file's memory segment is accessible to all functions defined in that VM file.
3) The values stored in the static memory segment persist throughout the life of the program.
Any implementation that we come up with that effects these three behaviors is acceptable.
Now let's consider the specified behavior of the assembler for a moment. We know that it will map each variable that it finds to a unique RAM location starting at address 16.
So the recommended (not required) implementation of the static memory segments is to turn each reference to a given index in a given VM file's static segment into a unique variable name in the unified assembly language file that is produced.
So consider two VM files, Fred.vm and Sue.vm, that contain a bunch of code but the following are the commands that reference the static memory segment.
Fred.vm:
in function f1:
pop static 3
pop static 0
in function f2:
push static 3
pop static 2
Sue.vm
in function s1:
pop static 0
pop static 1
pop static 5
push static 1
pop static 2
The VM translator can translate the .vm files in any order, so let's say that it translates Sue.vm and then Fred.vm. As it processes the file, any time it comes across a push/pop command referencing the static segment, it converts the index into a unique variable name by combining it with the file name and inserts that into the .asm file.
So in the .asm file, along with a lot of other instructions, we will have the following variables:
@Sue.0
@Sue.1
@Sue.5
@Sue.1
@Sue.2
@Fred.3
@Fred.0
@Fred.3
@Fred.2
When the assembler runs, it will assign these as follows:
RAM[16]: Sue.0
RAM[17]: Sue.1
RAM[18]: Sue.5
RAM[19]: Sue.2
RAM[20]: Fred.3
RAM[21]: Fred.0
RAM[22]: Fred.2
In general, the index used in a given VM push/pop command referencing the static segment tells you NOTHING about where in RAM that value will be stored -- not even where it will be stored relative to other indices in that same file's static segment. Each index simply maps to a uniquely named variable that the assembler will assign to a RAM location in the order that the assembler encounters references to variables.
This is quite different that the other memory segments. In all of the others, the index has to be an integer because the value of that integer has meaning in terms of the mapping. But in the static segment, we could actually relax the syntax and allow things like
pop static counter
push static total
because in this segment (and this segment only) the index is nothing more than an arbitrary part of a variable name.
|
|
Thank you for this. I was able to solve it, I think. In retrospect, this problem was not that difficult, but the VM emulator allocating the memory in an odd why and my false solution actually passing the test led me astray. In any case, just to be safe, I will send you the StaticTest.asm code my program created from StaticTest.vm. It would be awesome if you could have a look at it at your convenience and confirm that I am good to go, since I don't trust the StaticTest.tst.
|
Administrator
|
The static memory segment is probably the one that many people have the hardest time wrapping their head around but, at end of the day, is actually the easiest (non-virtual) segment to implement.
I'll be happy to look at your stuff, but be sure that it is annotated. I'm not going to spend a bunch of time trying to figure out which lines of assembly code go with which VM commands. The easiest way to do that is to echo each command to the .asm file as a comment before writing the instructions that implement that command.
|
|
I added annotations as you suggested and sent it to you.
Side note: I didn't really bother with optimization. At many points in the code, I estimate a few commands could be cut down. There are stuff like:
@SP
A=M
// some stuff here
@SP
M=M-1
Same thing can be achieved by:
@SP
AM=M-1
I left it as is because I thought it'd make debugging easier by reducing the amount of information on a given line. (Not sure how true this is, I suppose it reduces readability) I might go back in the future and fix those.
|
|
Ps Re reading your OP, I made this mistake too, and in fact so have many others. This may indicate "something" about the source material....
|
Administrator
|
kingofbuffs wrote
I added annotations as you suggested and sent it to you.
Side note: I didn't really bother with optimization. At many points in the code, I estimate a few commands could be cut down. There are stuff like:
@SP
A=M
// some stuff here
@SP
M=M-1
Same thing can be achieved by:
@SP
AM=M-1
I left it as is because I thought it'd make debugging easier by reducing the amount of information on a given line. (Not sure how true this is, I suppose it reduces readability) I might go back in the future and fix those.
I'll take a look at it when I can -- I have to use my other computer to access the necessary e-mail account, so it might be a bit.
Don't worry about optimizations yet -- getting correct results is all that counts. But do be aware that the VM translator is where the biggest gains (or losses) in compiler performance generally occur. Consider something like an add command that someone might implement with, say, ten instructions but that someone else might do in five. So the add command will run twice as fast. Now consider how many times a typical VM program is going to perform an add command. That one single optimization can result in very noticeable overall performance gain. It goes the other way, too. I've see the add command implemented in a way that takes twenty-one instructions, more than four times as long as it can be done.
So this is one area where performance should take precedence over readability, or at least direct readability -- but remember that you can inject as much annotative comments into the .asm file as you want and it has zero impact on performance.
Now, having said that, keep in mind that the compiler you write will not use your VM translator, but rather the VM Emulator, so there's not lasting penalty for doing a poorly optimized translator unless you want to eventually use your programs for the entire tool chain.
|
Administrator
|
Lozminda wrote
Ps Re reading your OP, I made this mistake too, and in fact so have many others. This may indicate "something" about the source material....
Very possible -- it'll be interesting to see how this is explained in the second edition.
But I think there are a small number of places where the authors left some things intentionally vague so that students, at least in a few places, have to dig down and struggle with figuring out something that is not obvious. That's one of the shortcomings of a project like this that has such a huge scope -- in order to be doable, a pretty clear roadmap has to be laid out from beginning to end, but doing so can eliminate most, if not all, of the opportunities to really develop engineering problem solving skills.
|
12
|