Purpose of 0-0
retromicro
Posts: 24
in Propeller 1
Hi
Please see the example code (ex07C) at http://www.cp.eng.chula.ac.th/~piak/project/propeller/machinelanguage.pdf under the section 'Enter self modifying code!'.
In there, it covers how to do indexed addressing.
I can see that the MOVS :access, #X stores the address of the 'array' into the ADDS sum, 0-0 instruction.
It looks like the ADD :access, #1 instruction moves the pointer into the array to the next value.
However, although the ADDS sum, 0-0 instruction must be the one to add the next array value to the total, what does the 0-0 mean ?
Thanks
Please see the example code (ex07C) at http://www.cp.eng.chula.ac.th/~piak/project/propeller/machinelanguage.pdf under the section 'Enter self modifying code!'.
In there, it covers how to do indexed addressing.
I can see that the MOVS :access, #X stores the address of the 'array' into the ADDS sum, 0-0 instruction.
It looks like the ADD :access, #1 instruction moves the pointer into the array to the next value.
However, although the ADDS sum, 0-0 instruction must be the one to add the next array value to the total, what does the 0-0 mean ?
Thanks
Comments
0 - 0 = 0
so
ADDS sum, 0-0
means
ADDS sum, 0
The use of 0-0 is just a convention. It's purpose is to indicate that the source field of the instruction will be modified by some other code. That is, it's a warning to the reader that this is self modifying code they are looking at.
I can see that the long at :access (which is where the ADDS lives) is being incremented by the ADD :access, #1
I know that this is to allow the next long to be read.
However ...
sum isn't even declared so how does the assembler know where to store the zero in the initial MOV sum, #0 ?
Why even add 0 ? The code is meant to be adding up the numbers as it goes round the loop. In the example above this one, the ADDS sum, r is very clearly adding the values in the longs to sum. In this case though, it's only seems to be adding the zero and doesn't seem to be keeping that running total.
Thanks again.
-Phil
Once the movs :rdval,r1 is executed the code becomes... The nop is required because modifying an instruction requires an instruction in between the modification and executing it (due to the pipelining in the cpu).
The second example replaces the 0-0 in the destination with r1.
BTW you will often see an "add dest,h200" instruction when looping. This adds a constant $200 (binary 10_0000_0000) to the instruction pointed to in the destination. This is adding 1 to the destination of the instruction because the first 9 bits are all 0's and are added to the source, and where the 10th bit is a 1 and added to the destination part. h200 will be declared as a long $200.
Much better than some long winded and non-standard comments at that point in the code.
"This zero is not really a zero, it's actually whatever value is written to the source field of this instruction by some other code before this instruction is run."
Nah.
That's not correct. It becomes:
The comment doesn't need to be long winded. It could just say "Source field modified at execution time". However, it is probably more fun to just put 0-0 and mystify the novice instead. After all, why should we bother using comments, or even documenting the code at all. It's much more rewarding to write obfuscated code.
Why not do both? Use 0-0, then add a short comment like: Source field modified by code
On the other hand comments can be clutter that just gets in the way and wastes time and mental energy: Comments need maintenance and often end up being confusing when they done get it properly, thus making them worse than no comment at all. The level of commenting called for may well depend on the intended audience. For example when I first discovered Javascript I might write: Because it's a kind of weird JS language feature that I was not used to. Later on I get used to it and such comments become annoying.
This is just a code snippet, that not will compile (assemble) as it is. For sure you need to declare a register sum, start the cog from Spin and so on.
I does not add 0, it would add the content of register 0, but this register address get replaced by the address of the register X, and later the address gets incremented to X+1, X+2 and so on.
Andy
I was thinking of movs :rdval,#r1 which I believe to be more common.
The gotch with the example is that only the lower 9 bits of the contents of r1 will be moved and this may very well not be what is required.
The result is more correctly
anonymous functions can't do is self-invoke since they don't have a name bound to them to allow a recursive call
(unless the language provides some sort of "recurse" syntax to allow this)
Mind you I tend to prefer referring to these things with the more common "Immediately-Invoked Function Expression" or "IIFE" : http://benalman.com/news/2010/11/immediately-invoked-function-expression which seems more accurate to me.
It is not an anonymous function. It has a name "f". See below. We can call it a "lambda" but there is more to the lambda idea than being anonymous. Anonymous functions can indeed call themselves: Mind you that is not allowed in ES5 strict mode. My example is not anonymous so it can, either directly or indirectly, like so:
This discussion and the included referrences are conclusive proof that my initial assessment was correct.
I had the same reaction 15 years ago.
We were so wrong!
JS is amazing. It's has features that Java and C++ are only recently catching up with.
This discussion and the included references only show that people don't understand the language.
It's OK that people don't understand JS. Nobody understands C++ either. But apparently that's OK.
In my experience so far JS can match C++ and Java, performance wise, for server tasks.
End of story really. Why suffer all that compiler Smile when you can, you know, get the job done.
Perhaps the primary reason I passed on it back-in-the-day was because everything I did involved driving I/O lines according to strict timing requirements. JS seemed the furthest thing from what was needed. But I'm at least a tad more eclectic in my programming nowadays. Perhaps there is a place for JS.
My eyes started to open a few years back when webgl in the browser was just becoming available. As an experiment the company I worked for let me put up a 3D, real-time, data visualization. Incredible, I found I can do blazing fast 3D scene rendering in the browser with a few lines of simple JS.
To make that thing work I had to create some server side code to parse a bunch of XML data streams, extract and filter this and that data and send it down to connected browsers. I had something of a shock when I found that JS running under node.js on the server could do all that with a performance almost matching similar server side code we had in C++ !
webgl and node.js were all very new at the time. So this whole project was a big gamble. I only had 4 weeks to pull it off. Including learning JS, node, and all the libraries from scratch. I don't think it would have happened on time if it was C++ I was learning from scratch.
A major factor in all this is that modern JS engines are no dumb interpreters they JIT the code achieve impressive performance.
But what about tweaking those I/O lines and typical MCU stuff? Well, there is JS on very small machines no a days. On a Raspberry Pi you can do some useful bit banging at quite a rate: https://www.npmjs.com/package/pigpio
But what about tiny MCUs? Well we have JS on those to: http://www.espruino.com/ Yep. Take C/C++ code. Compile it into JS with Emscripten: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Emscripten
A while back msrobots and I did exactly that. We got the open source Spin compiler to run in the browser. It's amazing that this actually works at a usable speed. Sorry I don't have the demo of that on line just now.
There are a bunch of other languages that "transpile" to JS as well now a days.
The bottom line here is that times have changed. Performance is cheap, memory is cheap, why not luxuriate an a language that is dead easy to use? Whilst being very well standardized and available on pretty much anything.
Ease of use trumps raw performance much of the time. That is why we have Spin on the Prop right?
We still have C/C++ for the really tough stuff.
the expression in which the function declaration occurs calls the function. Trust me I written enough compiler
back-ends to know how these things work. The callee thing is JS is exactly what I meant by
I trust you. It's only that the terminology we are using "Self invoking function", "Immediately-Invoked Function Expression", "IIFE" is used and abused, even by the "experts". Like a lot of other terminology.
The "callee" thing is an error in ES5 strict mode. So far I have failed to find an alternative way to have an anonymous function call itself. It's probably not something one should want to be doing