Shop OBEX P1 Docs P2 Docs Learn Events
Not very experienced with assembly — Parallax Forums

Not very experienced with assembly

Paul MPaul M Posts: 95
edited 2007-12-27 02:08 in Propeller 1
How do I pass multple parameters to an assembly routine when using:

cognew(@entry_address, parameter1)


How do I then access the parameters?

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-25 18:34
    Usually the (long aligned) address of a series of parameters is passed. That's how the PAR register was intended. The parameters are either copied to cog memory one at a time or as a block using a loop. The PAR register is always available to reload some parameters or to update their value in the hub memory. Look at any of the I/O drivers that are either included with the Propeller Tool or available in the Object Exchange for examples. The keyboard or FullDuplexSerial drivers come to mind as good examples.
  • Nick MuellerNick Mueller Posts: 815
    edited 2007-12-25 19:05
    And don't pass constants (as a general rule). Because they may be truncated. It is saver to only pass a pointer.

    So the cognew should look like this:
    VAR
      long paramBlock
    
    PUB
      paramBlock[noparse][[/noparse] 0 ]:= @someVar
      paramBlock[noparse][[/noparse] 1 ]:= 1234
      paramBlock[noparse][[/noparse] 2 ]:= @yetAnotherVar
    
      cognew(@theEntryPoint, @paramBlock)
    
    



    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]

    DAT
      org 0
      mov    ;ptr, PAR
      rdlong ;pPar1, ;ptr
      add    ;ptr, #4
      rdlong ;cPar2, ;ptr
      add    ;ptr,      #4
      rdlong ;pPar3, ;ptr
    
    ;pPar1 res 1 'pointer to parameter 1
    ;cPar2 res 1 'constant parameter 2
    ;pPar3 res 1 'pointer to parameter 3
    
    



    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
  • Paul MPaul M Posts: 95
    edited 2007-12-25 20:17
    Mike, Nick

    Thanks.
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-25 21:56
    @Nick: it is just "colon lower case p" you should avoid.. I think I mentioned that some days ago smile.gif

    @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.
    PUB
      pPar1 := @someVar
      cPar2 := 1234
      pPar3 := @yetAnotherVar
    
      cognew(@theEntryPoint, 0)
    
    ...
    
    DAT
      org 0
    theEntryPoint
    
    pPar1 LONG 0 'pointer to parameter 1
    cPar2 LONG 0 'constant parameter 2
    pPar3 LONG 0 'pointer to parameter 3
    
    



    Edit: changed a "p" to a "c"

    Post Edited (deSilva) : 12/26/2007 3:03:17 AM GMT
  • Nick MuellerNick Mueller Posts: 815
    edited 2007-12-25 22:14
    >@Nick: it is just "colon lower case p" you should avoid.. I think I mentioned that some days ago smile.gif

    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. smile.gif
    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. wink.gif

    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-26 02:59
    Nick Mueller said...
    So I consider that as bad style. But I know that I'm alone. wink.gif
    Not necessarily... But your advanced ideas of "namespace" do not match with SPIN; we had this discussion the other day wrt "local labels" within asembly code. The concept of "information hiding" is crude in the "PropellerTool", and much influenced by implementation constraints.

    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
  • Nick MuellerNick Mueller Posts: 815
    edited 2007-12-26 09:47
    > The concept of "information hiding" is crude in the "PropellerTool", and much influenced by implementation constraints.

    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
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-26 10:41
    Nick Mueller said...
    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".

    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.
    Nick Mueller said...

    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.

    What challenging software have you written for the propeller? Software where you are pushing the limits? Can I see your code?
    Nick Mueller said...

    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.

    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
  • hippyhippy Posts: 1,981
    edited 2007-12-26 11:26
    CardboardGuru said...
    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..

    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.

    DAT
                  org       $000
    
    Loop          call      #MySub1
                  call      #MySub2
                  jmp       #Loop
    
    ' ===================================
    
    REGISTERS     long      0[noparse][[/noparse] 10 ]
    REGISTERS_END
    
    ' ===================================
                  
    MySub1        mov       :a,:count
                  jmp       #:Return
    
    :org          org       REGISTERS
    :a            res       1
    :count        res       1
                  fit       REGISTERS_END
                  org       :org
    :Return
    MySub1_Ret    ret
    
    ' ===================================
    
    MySub2        mov       :a,:increment
                  jmp       #:Return
    
    :org          org       REGISTERS
    :a            res       1
    :increement   res       1
                  fit       REGISTERS_END
                  org       :org
    :Return
    MySub2_Ret    ret
    
    
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-26 12:05
    hippy said...
    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.

    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
  • Nick MuellerNick Mueller Posts: 815
    edited 2007-12-26 12:43
    > Well you'd certainly find that if you looked at my graphics drivers.

    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
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-26 12:50
    (a) variable overlay: It has been proposed - many months ago , I don't know by whom - to use naming standards, e.g. prefixing each "local" variable by the name of the routine it's used from. So an overlayed variable could look like this:
    sqrt_loopc
    div_loopc
    init_vaddr
                 LONG 0
    


    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
    VAR
      'this is the parameter block for ASM_ROUTINE
       LONG p1,p2,p3
      'here ends the parameter block for ASM_ROUTINE
    PUB
       COGNEW(@ASM_ROUTINE, @p1)
    {Note is is not even possible to name p1 ASM_ROUTINE_PARAMETERS, because VAR allows no overlaying}
    
    



    rather than
    PUB
    '  now setting the parameters for ASM_ROUTINE
       p1 := a
       p2 := b
       p3 := c
       COGNEW(@ASM_ROUTINE, 0)
    
    DAT
    
    p1 long 0
    p2 long 0
    p3 long 0
    
    



    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 smile.gif

    Post Edited (deSilva) : 12/26/2007 12:58:09 PM GMT
  • hippyhippy Posts: 1,981
    edited 2007-12-26 13:08
    One trick for overlaying named variables onto others as and where required is -

    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.
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-26 13:25
    hippy said...
    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.

    But what is the JMP for in the first place? It should work as:
    MySub1        mov       :a,:count
     
    :org          org       REGISTERS
    :a            res       1
    :count        res       1
                  fit       REGISTERS_END
                  org       :org
    MySub1_Ret    ret
    


    just as well!?

    Post Edited (deSilva) : 12/26/2007 1:33:22 PM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-26 14:01
    Nick Mueller said...
    Oh well. You never earned your living as a programmer. Right?

    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.
    Nick Mueller said...
    That code had to **work** and it had to be maintainable. Not just by me, or the idiot (who failed to fix his own code), but by others. It had to be readable. If you have ever programmed in a team with code of thousands of kLOC, you would't have made that statement.

    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.
    Nick Mueller said...
    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.

    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
  • Nick MuellerNick Mueller Posts: 815
    edited 2007-12-26 15:03
    > ... and the undesirability of globals in large programs ...

    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
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-26 15:54
    Just for the records: Nick's scenarios are not the standards in German SPUs. A team of highly skilled programmers is rare and I have never met a LARGE team of highly skilled programmers. When you are lucky the accountable manager (I do not refer to the team leader) has some understanding what is going on and what is needed. Development of safety critical software is tightly supervised by the customer. Issuing your own products and updates is dictated by sales, competition, and "management deadlines".

    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.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-12-26 16:22
    Certainly for the last 40-50 years, the most innovative work in software, hardware, or general engineering has been done by small teams of highly skilled people, often surrounded by small groups of equally skilled support people, particularly skilled in the "care and feeding" of bright, highly motivated individuals. Lockheed Aerospace had a facility that was known as the "Skunk Works" that worked this way and resulted in the Blackbird and the Stealth bomber and fighter which probably could not have been built in a conventional facility. The first commercial networked operating system (Datapoint's RMS) was done this way with a core team of 6-8 people and simply could not have been done with a larger group. The additional group dynamics and control functions needed for a larger group would have prevented the rapid creative exchanges and direct communication required for such an innovative project. This was done when Unix and the Ethernet were new (1970s). RMS allowed I/O devices and CPUs to be transparently shared over a wide area network, a fairly new concept at the time and not really duplicated since then.
  • hippyhippy Posts: 1,981
    edited 2007-12-26 16:24
    deSilva said...
    But what is the JMP for in the first place? It should work as...
    Absolutely right, that will work.
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-26 18:41
    Nick Mueller said...
    > ... and the undesirability of globals in large programs ...
    And because it is small by some standards, it doesn't need structure and clarity.
    If it looks bad, it is bad.

    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.
    Nick Mueller said...

    The only thing there is to understand:*It* *does* *not* *work*.

    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.
    Nick Mueller said...

    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"?

    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.
    Nick Mueller said...

    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 ...

    A fix to a defect on bad code doesn't have to be a hack. You can do good fix on bad code.
    Nick Mueller said...

    I would have fired you. Simply because you didn't come here and say that it needs a rewrite.

    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
  • mirrormirror Posts: 322
    edited 2007-12-26 22:33
    Nick, CardboardGuru,

    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.
  • Fred HawkinsFred Hawkins Posts: 997
    edited 2007-12-27 01:08
    Oh goody, a religion and politics thread!

    Kindling: Forth is more fun than Pascal. (Can-do Americanism meets stuffy EU professor and whips his butt)
    Firestorm: C sux
  • deSilvadeSilva Posts: 2,967
    edited 2007-12-27 02:08
    He was not an EU professor but an ETH professor...
Sign In or Register to comment.