We don't disagree about commenting code. I was of course being a bit extreme.
It's just that I get really annoyed by comments that only repeat what the instruction says anyway. "mov a, b ' Set variable a to the value of variable b". You know what I mean. Surprisingly common. It's just annoying noise.
I have been driven mad working on projects where the house rules demanded a comment for every line of code no mater if the line sensibly needed a comment or not Especially in high level languages.
I guess the amount and style of commenting should be targeted at the intended or expected reader. Like any writing.
I like to put some brief comments in source code to remind myself when I come back in a years time what on earth this thing is anyway and point out any odd tricks used in it's construction.
The 0-0 things seems to be working fine. There is a case for having a "?" or something to indicate "not defined until run time". A reader who is new to this would then be looking in the manual for the meaning of "?" where he would find the explanation.
I don't either, and yes, reading the above, we likely have more agreement on comments.
Redundantly redundant comments are noise, though I will find myself writing them when I'm really new to something. Seems to reinforce the basics. I'll delete 'em later, when or if I see them too.
Line comments that speak to intent actually make a lot of sense in assembly language. Each instruction can equate to a few words, the words form a story, etc... and reading that can be as valuable as the program code is. When done right.
For higher level things, that direct relationship tends to fall apart more. Agreed.
A little story. I have no idea if it is true or not...
A firm had hired a contractor for a few months to work with some project team on a big project. A year or so later, after he had left, there was an outstanding bug in the project. After much debugging effort, these "sometimes happens" bugs can be hard to find, the team homed in on a source file written by said contractor. And they identified the location of the bug. What was the comment they found there?
Oh, I thought it was obvious that I was just saying nothing. However, I think it's a good thing that I didn't explicitly include a comment in my post that indicated what I was trying to say. Otherwise, we couldn't have an endless discussion on the forum about what I intended "1 - cosine(0)" to mean.
movs sm1, #table ' no need for a label_name in front of instruction, compiler warns if movs vs movd is used incorrectly
...
mov t1, *sm1 ' code is data - data is code, can be changed on the fly eg self-modify
add sm1, #1 ' compiler warns that |<9 is needed if SMn is destination side
djnz t2, #loop
Hmm, Tony, no, I've had second thoughts, that sort of thing doesn't suit assembly. That very 1280x1024 example of Chip's above he uses add for self-modifying as much as he uses movd. Add only makes sense as a whole long operation.
But probably more importantly, symbols are never defined inside an instruction.
I think I like the 0-0 convention and a label on the left. With the right comments it's not hard to follow.
Actually ADD makes sense given the right operands. It's been used in some code to save on the MOV instruction. Just shift the increment bit over, until it lands in the S or D field to modify and go. Of course it's gotta be checked, but for known loops it's no big deal, and it's faster... And that, of course, requires a comment, or somebody needs to look at the code, see where the bit is, compare that to the instruction bit fields, then understand it's really ADDD or ADDS in concept, just with a clever operand.
This kind of thing is precisely why the mindset for assembly language just isn't the same as it is for higher level things. There isn't a planned notation for something like this, but it can make great sense to do. So it gets done.
Ditto to Heater and potatohead's comments on documenting intent in any kind of assembly code (and in high level language code as well). My mentors for 50 years (oh-my-gosh) of programming have all told me that any decent programmer can figure out what a specific instruction does ... the trick is to document why that way and what I'm trying to accomplish in terms of the larger function of the program or that portion of the program. Look at BB_i2cSpiInit.spin in BoeBotBasic for examples.
movs sm1, #table ' no need for a label_name in front of instruction, compiler warns if movs vs movd is used incorrectly
...
mov t1, *sm1 ' code is data - data is code, can be changed on the fly eg self-modify
add sm1, #1 ' compiler warns that |<9 is needed if SMn is destination side
djnz t2, #loop
That's an interesting idea. It might make the list of planned Spin extensions for my compiler. But why force it to be *sm[number]? Why not allow it to be anything? You could even have a local version, as *:field. It can have the same form as any other PASM label, except that it's defined mid-instruction with a unary prefix * and not at the beginning of the line.
EDIT: I might only add it in cases where the operand is a constant (so it only takes one instruction, to maintain determinism) and where a constant pool is defined (in case it doesn't fit in 9 bits).
thanks for the heated discussion. a related newbie question:
I came upon this while reading Jon McPhalen's WS2812 LED driver. He used this "self-mod" code to pass parameters from the main routine to a cog, as follows: (line: 121; file: jsm_ws2812_ss)
command := @resetticks
cog := cognew(@ws2812ss, @command) + 1
My question is, why not directly
cog := cognew(@ws2812ss, @resetticks) + 1
For example, I read Chip Gracey's Full-Duplex Serial Driver, line 47
okay := cog := cognew(@entry, @rx_head) + 1
@rx_head is the address of a VAR, which is also the first element of a bunch of paremeters (longs) passed into the new cog.
Wow. I can't believe that such a trivial matter has inspired so much commentary. (But I guess if I were snowed in, like so many are, I'd be doing a lot of navel-gazing, too. )
Anyway, there are several ways to cook this goose if you don't like 0-0. How about defining a constant like _TBD_ (to be determined) with a value of zero. Then use it in place of 0-0.
Now I've gotta go cut the grass while it's still warm out ...
>You could even have a local version, as *:field. It can have the same form as any other PASM label
I kind if like the idea that *[name] is a 9bit field label that can only be accessed by mov -s -d -i
And compiler will handle the warnings of wrong use of S, D and I for it.
You can even set up label names for the counter control register for example
org $1F8
long *ctramode:*ctrabpin:*ctraapin
long *ctrbmode:*ctrbbpin:*ctrbapin
You can even set up label names for the counter control register for example
org $1F8
long *ctramode:*ctrabpin:*ctraapin
long *ctrbmode:*ctrbbpin:*ctrbapin
Good idea - that would definitely be very useful. For consistency's and the compiler's sake, I think an "op" fake (i.e. like long or word or byte) instruction would be better/easier.
I'm considering allowing labels to conflict with special registers if there's no actually conflict. For example, the following would be valid:
org ctra ' not ambiguous - the following ctra and the real ctra are the same (because if they weren't it would be a compiler error)
ctra op #ctramode, #ctrabpin, #ctraapin
On a mostly unrelated note, there should also be flavors of if_ that let you explicitly specify which condition bits get set
I kind if like the idea that *[name] is a 9bit field label that can only be accessed by mov -s -d -i
And compiler will handle the warnings of wrong use of S, D and I for it.
That's no good. What if I want to update a source or destination address with ADD or any other instruction?
> What if I want to update a source or destination address with ADD or any other instruction?
I guess I meant the complier will not let you use regular mov to that label.
ADD and the other instructions will be checked for staying inside the 9bit field (if possible).
As the old system of doing thing is still there, you can use that for weird and unusual cases.
It's a very nice idea. The problem is it is not actually possible to do.
The assembler cannot know what values you are ADDing or ORing or whatever. Those values are not know until run time.
It's the quest for this kind of safety in program correctness that leads us to high level languages, the banning of self modifying code, of GOTO, the concept of data types and type checking, the banning of pointer arithmetic or even pointers at all. The removal of manual memory allocation.
It's a very nice idea. The problem is it is not actually possible to do.
The assembler cannot know what values you are ADDing or ORing or whatever. Those values are not know until run time.
It's the quest for this kind of safety in program correctness that leads us to high level languages, the banning of self modifying code, of GOTO, the concept of data types and type checking, the banning of pointer arithmetic or even pointers at all. The removal of manual memory allocation.
Before you know it you are programming in Java.
And still you have bugs in your programs:)
Absolutely 100% agreement here. The last thing I want to see is another set of rules, restrictions, and complications in assembler programming. Understanding all the basic instructions, flags, addressing modes, and other quirks is enough. The only additions I would not mind seeing are basic macro and conditional assembly capabilities.
Comments
We don't disagree about commenting code. I was of course being a bit extreme.
It's just that I get really annoyed by comments that only repeat what the instruction says anyway. "mov a, b ' Set variable a to the value of variable b". You know what I mean. Surprisingly common. It's just annoying noise.
I have been driven mad working on projects where the house rules demanded a comment for every line of code no mater if the line sensibly needed a comment or not Especially in high level languages.
I guess the amount and style of commenting should be targeted at the intended or expected reader. Like any writing.
I like to put some brief comments in source code to remind myself when I come back in a years time what on earth this thing is anyway and point out any odd tricks used in it's construction.
The 0-0 things seems to be working fine. There is a case for having a "?" or something to indicate "not defined until run time". A reader who is new to this would then be looking in the manual for the meaning of "?" where he would find the explanation.
I don't think that is ever going to happen.
Redundantly redundant comments are noise, though I will find myself writing them when I'm really new to something. Seems to reinforce the basics. I'll delete 'em later, when or if I see them too.
Line comments that speak to intent actually make a lot of sense in assembly language. Each instruction can equate to a few words, the words form a story, etc... and reading that can be as valuable as the program code is. When done right.
For higher level things, that direct relationship tends to fall apart more. Agreed.
A firm had hired a contractor for a few months to work with some project team on a big project. A year or so later, after he had left, there was an outstanding bug in the project. After much debugging effort, these "sometimes happens" bugs can be hard to find, the team homed in on a source file written by said contractor. And they identified the location of the bug. What was the comment they found there?
/* Insert correct code here */
That's my kind of comment
But probably more importantly, symbols are never defined inside an instruction.
I think I like the 0-0 convention and a label on the left. With the right comments it's not hard to follow.
No comment.
This kind of thing is precisely why the mindset for assembly language just isn't the same as it is for higher level things. There isn't a planned notation for something like this, but it can make great sense to do. So it gets done.
That's an interesting idea. It might make the list of planned Spin extensions for my compiler. But why force it to be *sm[number]? Why not allow it to be anything? You could even have a local version, as *:field. It can have the same form as any other PASM label, except that it's defined mid-instruction with a unary prefix * and not at the beginning of the line.
EDIT: I might only add it in cases where the operand is a constant (so it only takes one instruction, to maintain determinism) and where a constant pool is defined (in case it doesn't fit in 9 bits).
I came upon this while reading Jon McPhalen's WS2812 LED driver. He used this "self-mod" code to pass parameters from the main routine to a cog, as follows: (line: 121; file: jsm_ws2812_ss)
command := @resetticks
cog := cognew(@ws2812ss, @command) + 1
My question is, why not directly
cog := cognew(@ws2812ss, @resetticks) + 1
For example, I read Chip Gracey's Full-Duplex Serial Driver, line 47
okay := cog := cognew(@entry, @rx_head) + 1
@rx_head is the address of a VAR, which is also the first element of a bunch of paremeters (longs) passed into the new cog.
So what's the difference between the two?
Anyway, there are several ways to cook this goose if you don't like 0-0. How about defining a constant like _TBD_ (to be determined) with a value of zero. Then use it in place of 0-0.
Now I've gotta go cut the grass while it's still warm out ...
-Phil
I mean the cognew question.
That's more like it
I like _MORPHS_
-Phil
Have to agree with that. It stands out, is quick and easy to type, and fairly unique as well.
I kind if like the idea that *[name] is a 9bit field label that can only be accessed by mov -s -d -i
And compiler will handle the warnings of wrong use of S, D and I for it.
You can even set up label names for the counter control register for example
org $1F8
long *ctramode:*ctrabpin:*ctraapin
long *ctrbmode:*ctrbbpin:*ctrbapin
Good idea - that would definitely be very useful. For consistency's and the compiler's sake, I think an "op" fake (i.e. like long or word or byte) instruction would be better/easier.
I'm considering allowing labels to conflict with special registers if there's no actually conflict. For example, the following would be valid:
On a mostly unrelated note, there should also be flavors of if_ that let you explicitly specify which condition bits get set
I guess I meant the complier will not let you use regular mov to that label.
ADD and the other instructions will be checked for staying inside the 9bit field (if possible).
As the old system of doing thing is still there, you can use that for weird and unusual cases.
It's a very nice idea. The problem is it is not actually possible to do.
The assembler cannot know what values you are ADDing or ORing or whatever. Those values are not know until run time.
It's the quest for this kind of safety in program correctness that leads us to high level languages, the banning of self modifying code, of GOTO, the concept of data types and type checking, the banning of pointer arithmetic or even pointers at all. The removal of manual memory allocation.
Before you know it you are programming in Java.
And still you have bugs in your programs:)
Absolutely 100% agreement here. The last thing I want to see is another set of rules, restrictions, and complications in assembler programming. Understanding all the basic instructions, flags, addressing modes, and other quirks is enough. The only additions I would not mind seeing are basic macro and conditional assembly capabilities.