Shop OBEX P1 Docs P2 Docs Learn Events
what does "0-0" mean in propeller assembly code — Parallax Forums

what does "0-0" mean in propeller assembly code

iammegatroniammegatron Posts: 40
edited 2015-02-28 06:49 in Propeller 1
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".
«1

Comments

  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-22 09:31
    That is an indicator that some other instruction will modify the one containing 0-0. Props have no indirect addressing and no indexing either.

    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.
  • Heater.Heater. Posts: 21,230
    edited 2015-02-22 09:50
    iammegatron,

    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.
  • tonyp12tonyp12 Posts: 1,951
    edited 2015-02-22 10:32
    As you 99% of the time need to reset this value (inside a loop that gets repeated etc)
    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.
  • TubularTubular Posts: 4,702
    edited 2015-02-22 15:32
    Anyone know the history behind the 0-0 ? Where did it first appear?
  • Heater.Heater. Posts: 21,230
    edited 2015-02-22 16:06
    Interesting question.

    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:
    (function () {
        console.log("hi")
    }())
    
    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.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-22 16:10
    I recall that being discussed here. Old conventions brought forward to work easy with PASM.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-02-22 16:14
    Tubular wrote:
    Anyone know the history behind the 0-0 ? Where did it first appear?
    Mike Green and I started it almost simultaneously, IIRC. My use came from the old days of programming an IBM 1130, which also used self-modifying code. And I think Mike had probably programmed the same machine back when. The stylistic standard for the 1130 was *-*, where * was the virtual program counter. Had Chip introduced his program counter ($) with the first version of PASM, I probably would have chosen to use $-$ instead of 0-0. But the $ came after folks had already started using 0-0; so 0-0 stuck.

    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
  • TubularTubular Posts: 4,702
    edited 2015-02-22 16:25
    Very interesting. Thanks guys

    I've always thought we could come up with something more newcomer friendly, just don't know what
  • Cluso99Cluso99 Posts: 18,069
    edited 2015-02-22 19:01
    We used *-* on the System Ten assembler way back in the 70's. It was a 2 operand instruction set not unlike the prop.
  • Mike GreenMike Green Posts: 23,101
    edited 2015-02-22 19:17
    I don't remember where I saw this first, but it was sometime in the 1960s. The IBM 1401, IBM 1130, and IBM 1620 all used it, probably others as well. The idea was to have something that assembled to a zero value, but was eye-catching in the source code as something special, not to be confused with a zero.
  • Cluso99Cluso99 Posts: 18,069
    edited 2015-02-22 20:12
    Mike Green wrote: »
    I don't remember where I saw this first, but it was sometime in the 1960s. The IBM 1401, IBM 1130, and IBM 1620 all used it, probably others as well. The idea was to have something that assembled to a zero value, but was eye-catching in the source code as something special, not to be confused with a zero.
    Yes. The System Ten was actually released in 1969, and I would be fairly certain this was a copy of what had been seen elsewhere.
  • evanhevanh Posts: 15,921
    edited 2015-02-22 20:20
    I've just been perusing Chip's original VGA/SVGA drivers and I note he just filled it with the base symbol that the pointer calculation is derived from.

    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!
  • TubularTubular Posts: 4,702
    edited 2015-02-22 20:23
    EvanH somebody, I think maybe Rayman or Potatohead or Kye, went though and did a well commented version of the VGA driver
  • edited 2015-02-23 09:33
    evanh wrote: »
    I've just been perusing Chip's original VGA/SVGA drivers and I note he just filled it with the base symbol that the pointer calculation is derived from.

    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
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-23 10:24
    Yes, there are a couple of those around... The one I did is here somewhere, though I could not find it...

    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.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-23 10:28
    If you make changes to test, make one at a time.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-02-23 11:07
    I think the 0-0 convention is very confusing. It seems like this thread subject pops up a few times every year. In my opinion it would be much better to just use 0, and add a comment. Then there would be no confusion.
  • Heater.Heater. Posts: 21,230
    edited 2015-02-23 11:40
    Dave,
    I think the 0-0 convention is very confusing....this thread subject pops up a few times every year.
    Yes it is if you have never seen it before. And yes it does crop up often.

    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.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-23 12:10
    My thought too. That notation stands right out. Perfect.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-02-23 12:59
    Heater. wrote: »
    Which shows that this convention is working very well.
    I think it shows that the convention works very poorly if it needs to be explained to newbies. When I first started working with PASM I quickly learned about MOVS and MOVD, and how the Prop relies on self-modifying code. However, when I saw 0-0 it meant nothing to me, except that it was a silly way to represent zero. A well-placed comment saying that the source/destination address will be modified by a MOVS/MOVD before being executed would have made it very clear.
  • Heater.Heater. Posts: 21,230
    edited 2015-02-23 13:55
    Dave,

    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:
        move ?,3
    
    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.
  • tonyp12tonyp12 Posts: 1,951
    edited 2015-02-23 14:06
    I would take it one step further, the label name is part of the [?]

    movd labelA, #table
    ...
    move ?labelA, 3
  • evanhevanh Posts: 15,921
    edited 2015-02-23 14:19
    Just to reword what Heater has said, I think the good part about the recurring questions is that people are noticing and asking, as opposed to not noticing and having no idea there is self-modifying occurring. I only handled it easily because I was already fully aware that this is the Prop way.

    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.
  • evanhevanh Posts: 15,921
    edited 2015-02-23 14:35
    tonyp12 wrote: »
    I would take it one step further, the label name is part of the [?]

    movd labelA, #table
    ...
    move ?labelA, 3

    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.
  • Heater.Heater. Posts: 21,230
    edited 2015-02-23 14:45
    This whole business about comments in code, no matter if it's C or Spin or assembler is impossible.

    It all depends on the intended audience. Like any writing.

    For a beginner this may well be a God send:
        add x, z    'Add the variable z to the variable x 
    
    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:
        mov x, z    'Add the variable z to the variable x 
    
    Why? Because somebody, some time, has fixed a bug in the code and not updated the comment.

    Grrr....
  • evanhevanh Posts: 15,921
    edited 2015-02-23 16:51
    Heater,
    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.
    ' Build two scan lines during four scan lines
    
    build_2y                movd    pal,#linecode           'reset palette/pixel pointers
                            movd    pix0,#pixels0
                            movd    pix1,#pixels1
    
                            mov     ina,#2                  'four scan lines require two waitvid's
    
    build_40x               mov     vscl,vscl_two_lines     'output lows for two scan lines so another
                            waitvid hv_sync,#0              '..cog can display while this cog builds
    
                            mov     inb,#xtiles / 2         'build half of two scan lines
    
    build_1x                rdword  vscl,ctrb               'get tile-selector word from tile-map
                            add     ctrb,#2                 'inc tile-map ptr
                            ror     vscl,#10                'select tile palette index, roll the 10-bit tile index to upper bits
    pal                     movd    linecode,vscl           'put lower 9 bits as palette ptr in pre-built raster routine, 6-bit zero paged address
                            add     pal,d1                  'inc above ptr to next pallete instruction of raster routine, d1 => dest field += 2
                            shr     vscl,#16                'shift the 10-bit tile index back to bits[15:6]
                            add     vscl,tile_line          'select associated current tile line address, bits[5:2]
    pix0                    rdlong  pixels0,vscl            'get tile_line_+0 pixels and store in raster buffer
                            add     pix0,d0                 'd0 => inc dest field
                            add     vscl,#4                 'select next tile line address
    pix1                    rdlong  pixels1,vscl            'get tile_line_+1 pixels and store in raster buffer
                            add     pix1,d0
                            djnz    inb,#build_1x           'loop for next tile encoding (16 inst/loop, 640 inst/40 loops)
    
                            djnz    ina,#build_40x          'loop for second half of two scan lines(~645 inst/loop)
    

    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.
  • Heater.Heater. Posts: 21,230
    edited 2015-02-23 17:14
    A good example.

    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.
  • evanhevanh Posts: 15,921
    edited 2015-02-23 17:42
    Here's the same source as original from "vga_1280x1024_tile_driver" from the ESC demo archive of 2007.
    ' Build two scan lines during four scan lines
    
    build_2y                movd    pal,#linecode           'reset palette/pixel pointers
                            movd    pix0,#pixels0          
                            movd    pix1,#pixels1          
    
                            mov     ina,#2                  'four scan lines require two waitvid's
    
    build_40x               mov     vscl,vscl_two_lines     'output lows for two scan lines so another
                            waitvid hv_sync,#0              '..cog can display while this cog builds
    
                            mov     inb,#xtiles / 2         'build half of two scan lines
    
    build_1x                rdword  vscl,ctrb               'get word from tile array
                            add     ctrb,#2                  
                            ror     vscl,#10                'get tile palette code
    pal                     movd    linecode,vscl
                            add     pal,d1
                            shr     vscl,#16                'get tile line address
                            add     vscl,tile_line                                   
    pix0                    rdlong  pixels0,vscl            'get tile line +0 pixels
                            add     pix0,d0                                  
                            add     vscl,#4                                  
    pix1                    rdlong  pixels1,vscl            'get tile line +1 pixels                 
                            add     pix1,d0                                  
                            djnz    inb,#build_1x           'loop for next tile (16 inst/loop)
    
                            djnz    ina,#build_40x          'loop for second half of two scan lines
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-02-24 03:54
    So if I understand the rational for 0-0, it is good because it obfuscates the code and forces the programmer to ask what it means on the forum. So a good approach to coding is to obfuscate it so that people will be forced to post to the forum to get answers. And that comments are bad because they will aid the programmer in understanding the code, and will reduce their need to ask questions on the forum.

    Makes sense to me. :)
  • potatoheadpotatohead Posts: 10,261
    edited 2015-02-24 09:40
    It's not that extreme.

    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.
Sign In or Register to comment.