Not very experienced with assembly
Paul M
Posts: 95
How do I pass multple parameters to an assembly routine when using:
How do I then access the parameters?
cognew(@entry_address, parameter1)
How do I then access the parameters?
Comments
So the cognew should look like this:
The ASM looks like this:
[noparse][[/noparse]Stupid formatter! if your read a ";", replace it with ":". Had to do it that way or some chars were eaten up]
Edit:
Edited to make clear that you should not pass constants as second parameter to cognew. You can pass constants in the parameter block
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
Post Edited (Nick Mueller) : 12/25/2007 8:58:51 PM GMT
Thanks.
@Paul: Another technique some (me, too!) like better to "parametrize" a COG is this (using Nicks example)
It makes many thing more obvious and saves COG space. I am sure I mentioned all this in my Tutorial.
Edit: changed a "p" to a "c"
Post Edited (deSilva) : 12/26/2007 3:03:17 AM GMT
Ah well. Since decades, I name all pointers starting with a "p". The forum-software won't change that.
And also a "[noparse][[/noparse] 1 ]" without blanks. Have problems typing that too.
> It makes many thing more obvious and saves COG space. I am sure I mentioned all this in my Tutorial.
I hate cluttering the namespace.
It also hides (to some extend) where the parameters come from and looks awkward if you have more than one instance of that "object" with different parameters. So I consider that as bad style. But I know that I'm alone.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
There is a much to high barrier between "objects" and nearly no barriers within one object. Using locals in PUB and PRI methods works fine, but they are constrained to be non-preset LONGs and so you have to make a thing global just because it is a BYTE, or you like to preset it.
That the compiler cannot distinguish whether you allocate code for a COG or layout your own global preset variables, does not make things easier...
Post Edited (deSilva) : 12/26/2007 3:15:39 AM GMT
Sure. I'm aware that assemblers somehow *have* to be crude.
What I'm suggesting is to use parameters to make clear *when* and how the data for initialisation flows. I won't tell names to protect the innocent <G> but the ASM code I'm currently working with (not my code!) exclusively is using public labels. For each and every register! Even for the dumbest local scratch register. Roughly 50 and only about 10 of them are actually accessed from "outside".
What I'm preaching is:
Make clear how the data flows and use the concept of scope.
Even if it wastes a few longs. If you need to make performance tuning, do it when everything works and is rocksolid. But start with a clear concept.
Sidestory:
I'll never forget that idiot that was hired together with his "almost working" word processor (in Modula). It took me two months to get rid of all the globals he has been using (even 3 different ones with exactly the same contents). Later, I was responsible for the programmers (and it was a software-company!) Some years later, I urged the boss to fire him. He didn't, so I left. No more RCS, no more Bug-tracking ...
Three years later, they no longer made their own software.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
Well you'd certainly find that if you looked at my graphics drivers. This notion that you have that there is a namespace to be polluted by data labels is Quixotic. It's something that you've taken from other programming environments and tried to apply to the Propeller just because you're inflexible. In a Propeller assembler routine you are limited to 496 longs of instructions or data. Do anything moderately challenging and you'll be fighting for every LONG. And that means you can't for example have a different register called "count" or "i" for every place in an assembler program that needs a loop. You declare one, and you reuse it everywhere, till there's a nested loop, and you declare another global "count2" or "j". Which you also reuse elsewhere.
What challenging software have you written for the propeller? Software where you are pushing the limits? Can I see your code?
You *ARE* Don Quixote. Just because a company you used to work for does not do software any more does not provide evidence that you were the hero programmer, and by not following your ideas, they failed. They might just have easily failed because you wasted 2 months refactoring code rather than fixing the defects with as little code churn as possible.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Help to build the Propeller wiki - propeller.wikispaces.com
Play Defender - Propeller version of the classic game
Prop Room Robotics - my web store for Roomba spare parts in the UK
Post Edited (CardboardGuru) : 12/26/2007 11:03:19 AM GMT
It is possible to have locally scoped variables for assembler routines ( re-using the same scratch area, with all the potential conflict issues that brings with it ) with a bit of juggling and through-hoop jumping. I'm using this trick so "count" in one routine and "increment" in another re-use the same location but have names sensible for their local use.
It gets more complex for nested routines, especially when trying to allocate variables in the scratch area by hand.
An interesting approach. But as you know wastes one long per subroutine, and is rather less readable than:
count
increment res 1
An approach which I have tried. But those conflict issues are deadly. Now I tend to just use one label per memory location, and for real local temporary variables, go old school and use general purpose register names r0,r1...rn, together with a comment to say what it currently represents at the point of setting it. Plus count etc. for loop indexes. That way makes it clear that specifically named labels I can count on to be untouched by anything else, but the general purpose register names are used for other things.
The real scope issue, that an actual data location is only used by one routine for one purpose, is not helped by any trick of labeling. It's an inevitability that challenging ASM routines are pushing the boundaries of 496 longs and data locations do need to be reused for multiple purposes. The only way of managing that is by the intelligent programmer dealing with it on a case by case basis. This is why it's called hand crafted assembler.
And this certainly isn't a deficiency of the Propeller. On most processors you'd be dealing with a small fixed number of named registers which are reused everywhere. At least with the propeller, the number of these general purpose registers is flexible.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Help to build the Propeller wiki - propeller.wikispaces.com
Play Defender - Propeller version of the classic game
Prop Room Robotics - my web store for Roomba spare parts in the UK
No, that wasn't you. But it also doesn't matter at all.
> This notion that you have that there is a namespace to be polluted by data labels is Quixotic.
Maybe for you?
> It's something that you've taken from other programming environments and tried to apply to the Propeller just because
> you're inflexible.
I call that educated, experienced.
> Do anything moderately challenging and you'll be fighting for every LONG.
I don't fight for longs, I fight for res.
> And that means you can't for example have a different register called "count" or "i" for every place in an assembler
> program that needs a loop. You declare one, and you reuse it everywhere, till there's a nested loop, and you declare
> another global "count2" or "i". Which you also reuse.
I think you never had a concept about scope. I'm working within a limited environment (a COG) and I really don't want to care how a register has been called for an other COG. Period. Globals don't serve here, they fight.
> What challenging software have you written for the propeller? Software where you are pushing the limits? Can I see your code?
You certainly won't see that code. Maybe some part.
But I can tell you that it is a ignition system for combustion engines. Some specs?
* 24 cylinders (or more under certain circumstances)
* max 60000 RPM
* ignition advance by RPM and load (table driven. Don't know the english expression, but in German it is "Kennfeldz
This would allow convenient checking when you have established the control flow.
(b) A terribly weak point of the Propeller is parameter passing on all levels. There are very good reasons why microprocessor architectures keep to stack instructions - inefficient as they may be. It is a very, very, very convenient way to work around many of the problems we are fighting here.
(c) I do not see that it is more transparent or obvious writing
rather than
In fact my proposed technique comes very close to
ASM_ROUTINE(a,b,c)
when used with discretion.
There is a minor functional drawback, as this is a strict "call by value" rather than the (first example) "global call by reference". However Nick should consider this an advantage, rather
Post Edited (deSilva) : 12/26/2007 12:58:09 PM GMT
org r0
firstVar res 0
org r7
secondVar res 0
But when used in-line ( so vars are localised to a routine ) the cog address org needs to be retained then restored for the subsequent code.
One solution for the wasted long ( 'jmp #:Return' ) noted in my example code earlier is to make those 'Jmp #CommonReturn' and then call all subs with 'jmpret CommonReturn,#MySubN'. Again that creates problems with nested routines sharing a common return point but can also be worked round.
A compiler or decent macro assembler should be able to generate suitable code in an elegant, simple and readable fashion but hand crafted raw assembly requires that we understand what we are writing and using which complicates matters. It's a bit convoluted to do in PASM but not really much worse than in other assemblers I've used. It takes some effort, but get the framework right and it all works quite well. The PropTool could make things easier but it's a fact of life that it only does what it does.
But what is the JMP for in the first place? It should work as:
just as well!?
Post Edited (deSilva) : 12/26/2007 1:33:22 PM GMT
No, very wrong. I worked as a programmer from the mid 1980s through till the mid 2000s, latterly on a mobile phone OS. I understand scope perfectly, and the undesirability of globals in large programs - The OS I worked on didn't allow any writable globals at all (well at least in DLLs, which was most code), and the source consisted of literally thousands of files of C++ and assembler. What I don't do is try to apply the conventions that were there for a reason on that platform to another platform that has completely different opportunities and limitations.
However, you are inflexible and don't adjust to different platforms well. In a number of threads you've created a whine fest based on your lack of ability to think in different way for a new platform.
Doubly wrong.
As I said, not just thousands of lines of code but thousands of source files, and in my turn gatekeeper and build master for it. The point you are missing is that there is a time for writing for writing elegant code, but in shipping products, there is also a long time of keeping code churn to a minimum. There's a place for refactoring code, but most of the cases where someone calls the previous programmer an idiot, and wants to make widespread changes to how an existing functioning program works, they do so because of lack of understanding, rather than more understanding. The number one task of a gatekeeper is to prevent changes getting into the release build which are refactoring for the sake of a particular programmer's sense of aesthetics, whilst letting through real necessary defect fixes.
Another cog? Use a separate object for each cog which runs different code. That's the norm. File scope is all the scoping you need there. That's more an issue of modularization rather than scope.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Help to build the Propeller wiki - propeller.wikispaces.com
Play Defender - Propeller version of the classic game
Prop Room Robotics - my web store for Roomba spare parts in the UK
And because it is small by some standards, it doesn't need structure and clarity.
If it looks bad, it is bad.
> As I said, not just thousands of lines of code but thousands of source files
What's so hard to understand with "thousands of kLOC"?
> However, you are inflexible and don't adjust to different platforms well.
<G>
> There's a place for refactoring code, but most of the cases where someone calls the previous programmer an idiot,
> and wants to make widespread changes to how an existing functioning program works, they do so because of lack of
> understanding, rather than more understanding.
The only thing there is to understand:
*It* *does* *not* *work*.
Now try it with the initial programmer: "Can you fix this?". "Yes", "How long does it take?" "One week"
When you come back 3 weeks later and he claims it works right now (but it doesn't) would you call him smart? And if that part of code is needed and is just a pile of spaghetti-code, what would you do? And if you ask him what that variable is for and the only answer is "No clue"?
OK, *you*'d hack it somehow until the next error pops up and you hack it and you get the next bug-report and you hack ...
I would have fired you. Simply because you didn't come here and say that it needs a rewrite. "How long does it take?" "Don't know" "Why?" "Look at that mess, here ... here .. here" "OK, make a rewrite".
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
The amount of irrationality is rather high. It is rare that the best appropriate tools are used (they are generally not even known) or that the most skilled persons do the most critical work.
Nick's approach is well meant but I have never seen a success from that.
o.k. It is most likely all the same all over the world.
It doesn't need THE SAME treatment as large programs with large resources. Programming for small devices with limited resources is a different thing. Agin, you are too inflexible to change what you do to suit the platform. There is nothing unstructured or unclear about globals. Like every other possibility they have their place. And in embedded programming it's a rather bigger place than in large systems. Size does make a difference.
If it didn't work at all, your company wouldn't have taken it on. What you described is poor quality code that has defects, not code that does not work.
As a gatekeeper I don't ask him to fix it in the first place. There's a process. His team (might just be him) has reported defects with priorities. He needs to reproduce the defect, provide a diagnosis, code a fix, test it, prove that he's done all of these things, and convince me that it's a decent fix when he applies to submit it to the build. If the fix is in as bad a shape as you say the original code is, then he'll be told to go away and submit a better fix.
Just as your refactoring which isn't directed at fixing a particular defect wouldn't get past me either.
Underlying both these denials is the rule that any fix must be both correct and minimal.
A fix to a defect on bad code doesn't have to be a hack. You can do good fix on bad code.
I'd never have hired you in the first place. Seriously, you need to read about all the products that never shipped, or shipped too late and lost the market because some unrealistic and arrogant programmer(s) thought it would be a good idea to rewrite the code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Help to build the Propeller wiki - propeller.wikispaces.com
Play Defender - Propeller version of the classic game
Prop Room Robotics - my web store for Roomba spare parts in the UK
I think you really do agree with each other much more than·what you're giving·credit. You both make valid points.
There are *idiot* programmers out there. A number of years ago I was hired (as a contract programmer) to help out with an embedded project. The·lead programmer (also on contract) was charging more and more, and achieving less and less towards the completion of the project - which had deadlines with quite severe penalty clauses. The processor used was an 8051 variant for which 30000 lines of assembler had been written over the course of about 9 months. It was hard to read,·difficult to debug, and almost impossible to modify. It had some clever stuff in it, but the programmer had "clevered" himself·into a corner. I tried modifying the original, but it was just a hopeless state of affairs. After about 3 months I managed to convince the company to get rid of the other programmer and to allow me to do a complete rewrite of the software.·In two weeks I churned out about 3000 lines of C code to replace the functionality of the assembly code, and went on to write another 7000 lines of C code·over the next three months to implement the rest of the functions required. The final product had about 100 lines of assembly code. The project·was completed on time - just - literally on the night before the penalty clauses were due to start taking effect.
The final project had a generous share of global variables and structures. One advantage of global variables is that they don't have to be passed around as parameters! The other programmer thought he needed assmbler to get the required speedup - what he needed was a·lot of global variables and structures and a collection of intelligent functions to deal with them, as parameter passing would have caused enough of a slowdown to kill the project.
I would like to offer a suggestion (definition):
Good Code : Code that is understood / debugable / expandable by it's programmer.
Bad Code : All the code that's not Good Code.
The *idiot* programmers are those who pretend to be more than what they are - we all program bugs into our code, it's how we structure our world (our programs)·to·catch and eliminate those bugs which makes all the difference.
One thing I've learned over the years - If you've ever·fixed a bug by accident (you don't know why), then you haven't fixed the bug, all you've done is masked it.
Kindling: Forth is more fun than Pascal. (Can-do Americanism meets stuffy EU professor and whips his butt)
Firestorm: C sux