what does "0-0" mean in propeller assembly code
iammegatron
Posts: 40
I've seen several times, instructions like this:
rdlong 0-0, r1
or
adds sum, 0-0
isn't "0-0" the same as "0".
rdlong 0-0, r1
or
adds sum, 0-0
isn't "0-0" the same as "0".
Comments
It is common to keep an address or value somewhere, increment it, modify an instruction, do something, then repeat.
Look a bit farther up the code. You should see a loop of sorts containing one or more instruction modify instructions, MOVS, MOVD, etc...
"0-0" resolves to the value 0. It gets changed at runtime.
It's all about "self modifying code".
That "rdlong 0-0, r1" would normally read from address 0 in HUB that is 0-0 as you say.
But what is intended here is that that very instruction will be used to read from many HUB addresses, say reading through an array within a loop.
To do that the instruction's dst field needs to be changed to read from the desire HUB address. Self modifying code.
The 0-0 notation is just to alert the reader to the fact that this instruction will be modified by code elsewhere at run time.
Presumably there is a label on that instruction, so you can use that to find where in the code the modification is made.
So you don't use the initial value, but put a zero-minus-zero (=0) as it will be filled in by a movs or a movd outside this loop anyway.
I have no idea where the "0-0" thing came from. I would not be surprised to find that such a convention dates back to the mainframe computers of the 1950's where such self modifying code was very common.
Programmers have many such conventions. Like using the hex value 0xDeadBeef to mark the end of stack or other parts of memory where a program should not tread. Makes it easier to look for in core dumps.
Or wrapping self-calling functions in JavaScript with round brackets: Serves no purpose but to alert the reader up front that this function is a little bit special.
Anyone know any more such programming conventions in other languages perhaps. A collection of these would make a nice nerdy geek web page.
Incidentally, CALLs on the 1130 had only one address, instead of the Prop's two. The first "instruction" in a subroutine is where the return address got put, and the second instruction is where execution actually began.
-Phil
I've always thought we could come up with something more newcomer friendly, just don't know what
BTW: Chip really could have added a little more in the way of in-line comments. Keeping my head around how the traversing is done is not always that easy!
I think that Chip sees this stuff as being so obvious it doesn't need comments haha.
Sandy
How to make good use of the TV and VGA drivers is in my signature.
If you have questions, ask them. Maybe we can just get another commented version.
The difficult parts of Chip's work are the tasks, which get done during short blanking periods, and the palette tile mappings, which are somewhat commented in my sig.
The tasks allow the driver to change the display dynamically. You might find some of the simpler TV and VGA driver code in the OBEX better commented to start.
Most of us trudged through Chip's work, learning a lot. Worth it.
I personally mapped it out on paper the first time. Follow it through an entire frame. Then break out the tasks, which will leave you with the core of how one is done. If you want, set constants, strip out the tasks and test what you understand.
Which shows that this convention is working very well.
Basically, if you are an old hand who has seen this kind of thing before it stops you in your tracks, alerts you to what is going on, you figure it out, and you continue.
If you are new to this, it stops you in your tracks, you get very puzzled and end up asking WTF here on the forum. Then you become an "old hand".
Job done. No comments required.
I hate most comments in code. They are either obvious repetitions of what is written in the code anyway or dangerously out of date.
No, of course, it's not a silly way to represent zero. It's a way to indicate "not determined until run time"
On reading that one would surmise that either the programmer is an idiot, or he is trying to say something. It's a way to indicate that something odd is afoot here.
How clear could it be?
Comments are nice and all. But over the years I have learned to hate them. As I said they are either a repetition of what the code says anyway like: "Add one to the variable A" or very soon out of date with what the code actually does.
Give me a "0-0" any day.
Edit: Thinking about it, perhaps a language that depends on such self modifying code should allow for an explicit place holder for the position that is to be modified at run time. For example: That would leave no doubt in the mind of the reader of the source code that he has no idea what happens until run time.
movd labelA, #table
...
move ?labelA, 3
On the comments issue, I am learning PASM details right now, I've still not written a single program for the Prop, so am probably writing a bit of "add variable a to b" type stuff, but there is two types of comments I'm finding very useful:
- One is tracking of detailed bit flows, ie: what parts of the encoding is going where.
- The other is register reuse/alternate use, particularly the way Chip uses the shadow registers or because of his intimate knowledge of when a special register can be used as scratch. A variant of this is I sometimes extend symbol naming to make it clearer the differences between say lookup encodings, lookup indexs/ptrs and the looked up value.
That's a good idea. Though, Chip had a convention of sorts in the VGA drivers of labelling the modified instructions with a colon as first character of label rather than a question mark.
EDIT: Okay, it's use was pretty random really. Maybe just a way of having more labels/symbols without having to think of more names.
It all depends on the intended audience. Like any writing.
For a beginner this may well be a God send: Why? Because they are not used to the order of things. Does z get added to x or does x get added to z?
But soon, as you start to understand what is what, all this become annoying noise.
And then you find yourself confronted with a new code base with things like: Why? Because somebody, some time, has fixed a bug in the code and not updated the comment.
Grrr....
Below is example of what I meant. There was some comments by Chip already but a lot has either been rewritten or added myself without changing a single line of code or even any symbols this time.
EDIT: I guess, being assembly and being timing sensitive and being self-modifying and being packed to fit in tight space means there is lots of convolution. The source code itself is not so self explanatory.
On the one hand we have to understand what on earth is this code supposed to do?
In this case it looks like some video driver. Do we know the spec. for that exactly?
Then we have to work out how this code is supposed to meet that specification.
Can you write the requirement spec into the code?
Can you understand the code without the requirement spec.?
Grrr... It's not easy.
Makes sense to me.
One could just put a 0 in there. The very first time I saw 0-0, it worked like a flag. "Why is that there?" And it's that use as a flag that works out reasonably. Code clarity isn't changed much, but the programmer sees something that is very highly likely to pique their interest.
...and they aren't forced to ask. Truth is, PASM isn't all that complicated. A quick look through the program shows the MOVD instruction and friends, right? If somebody were parsing through a bit of code, they would run into those before seeing the 0-0, and may well understand it before really having to think about it much.
For that case, it's unimportant what gets put there.
For other cases, having it be notable does invoke the question. They may ask here, they may dig deeper, they may search for it online, whatever.
I very strongly disagree with Heater on comments. The best ones are those that speak to the intent of the code, and or include some theory of operation and other "good to know" or "need to know" types of information. These are often quite useful even when the comments aren't aligned one for one with code, like when it's not all updated on a change. No big deal.
The least valuable comments to me are those that describe the instruction operation. Of course, the instruction already does that!
One could put, "This, modified by..." on that 0-0 instruction too. And I think I have done that in some of my PASM in the past.
Additionally, the amount of effort required to formalize and expand PASM to specifically address self-modifying code isn't worth it. That's my own value judgement, of course, but it's very common for assembly language, and machine language programmers to use various kinds of notation to handle self-modify and or "off label" instruction uses.
One of the nice things about assembly language is the fact that the programmer gets to do anything they want to. On more capable systems, this is limited by execute mode on some CPUs, but overall remains true.
So then we are left with "have cake and eat it too" kinds of discussions.
Assembly language is going to require people do some thinking, and alerts, hints of any kind at all, become extremely valuable. It is common to trace through a bit of code, make notes, etc... to understand what it's purpose is and how it operates. PASM is very highly readable assembly language! Beautiful actually. It's almost completely free of odd instruction tricks, and other things we very frequently find in assembly language land. Having a few things to learn is very minor league. Getting to them, or being made aware of them makes perfect sense.
This nature is the "have cake" part. It's powerful, flexible, and so forth. We've seen every trick in the book get used well, and there may be tricks left yet. If some of the trick cases were formalized, we would have a "works great, but that's not how we code it normally" discussion, which isn't really much different from this one. And this is going to vary, AS IT SHOULD.
The "eat it too" part, is somehow believing we can design away, or improve on, or present assembly language programs in ways that do not require people to parse through and really understand what is happening, or that communicate that complex understanding via syntax and a hint or two.
Over the years, I've looked a lot of assembly code. Know what I look for right away?
Differences from the norm. Why?
Because that is where the magic is. In fact, it's nearly always were the magic is. In this sense, that 0-0, gets right to where the good stuff is happening. It's saved time, and it can put somebody right where they need to focus their attention. All of the other details are rather ordinary, and for a new programmer, will need some thought. For others, it's the "look here" flag needed to get right at the heart of things, the rest may be entirely optional, depending.
For higher level stuff, this kind of dynamic does not play out the same way, though it can. And it's worth differentiating the assembly language mindset as just that little bit different beast it is.
Edit: Just saw the loop evan posted above. Yeah, that works. And the comment adds a lot of value too. Seeing the word "pointer" is high value. Seeing the instruction label as destination stands right out too. A quick lookup on MOVD should tell somebody what they need to know about that loop.
No matter what though, a programmer is going to have to parse through that loop. Could be a generic thing in there, or a label, or comment, or... whatever. Again, this is more or less expected in assembly language land. We will have our preferences, and some of those may end up being centers of significant gravity, while others might just be one offs for a given programmer too. That's just how it's going to be.
One last thing: The word "pointer" could also be "index" or some other basic thing associated with addressing. The 0-0 bit implies this stuff, and how relevant it is really depends on ones experiences. When looking at assembly language, it's important to look for bits of relevance. Some are more common than others, and they vary by our experiences. Over time, people track these things down and the number of references they can associate in a meaningful way goes up. There just won't be one universal notation, again due to how assembly language is.
In the case of the code evan put here, somebody is going to ask, "Why is an instruction the target?", instead of, "Why does this instruction have 0-0?" Both questions take somebody to the intent. Working from the target back to the modifying instruction is one way, and working from the modifying instruction toward the target is another way. Both are perfectly fine, common sense ways.