Shop OBEX P1 Docs P2 Docs Learn Events
Problem with assembly code — Parallax Forums

Problem with assembly code

Chad GeorgeChad George Posts: 138
edited 2008-01-05 23:55 in Propeller 1

EmptyLocalBuffer
                        mov     t0, #8
ZeroLocal               mov     Buffer+0, Zero
                        add     ZeroLocal, incrDest
                        djnz    t0, #ZeroLocal
                        
EmptyLocalBuffer_ret    ret

Zero       long $00000000
incrDest  long %10_00000000
Buffer     long 0,0,0,0,0,0,0,0

t0           res 1





Is there something wrong with this code?
It doesn't seem to work and I can't figure out why not.

-Chad

Comments

  • deSilvadeSilva Posts: 2,967
    edited 2008-01-05 02:11
    There is nothing wrong with that code as such... How do you know it does not work?
    E.g. you can put it into some debugger. Ale's pPropellerSim is the most recent one... You have to modify for it, as it does not yet accept constant expressions and preset sequences in a line.

    So your problem is on a higher level...
  • Mike GreenMike Green Posts: 23,101
    edited 2008-01-05 02:14
    This will only work once since ZeroLocal is not reinitialized. Other than that it looks (in isolation) like it should work.
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-05 02:35
    Yes Mike - it only works once smile.gif
    And does horrible harm at the second call
    Edit: Though my analysis was absolutely correct, it was a little bit - succinct

    Post Edited (deSilva) : 1/5/2008 2:42:01 AM GMT
  • Chad GeorgeChad George Posts: 138
    edited 2008-01-05 03:06
    Yes, it is shown in isolation.

    I suspected something else was the problem, but I set an led right before returning and it doesn't turn on unless the "add ZeroLocal, incrDest" line is removed.

    In the same application this code works fine:

    EmptyLocalBuffer
                            mov     t0, #8
                            mov     t1, #Buffer+0
                            movd    ZeroLocal, t1
                            
    ZeroLocal               mov     Buffer, Zero
                            add     t1, #1
                            movd    ZeroLocal, t1
    
                            djnz    t0, #ZeroLocal
    EmptyLocalBuffer_ret    ret
    
    



    Still don't know why the other didn't.
  • Chad GeorgeChad George Posts: 138
    edited 2008-01-05 03:08
    One other question.
    Does the propeller do any pipelining?

                           movs    GetLocal, StoreAt
                            nop
    GetLocal                mov     data, Buffer+0
    
    


    seems to work, but ...
                           movs    GetLocal, StoreAt
    GetLocal                mov     data, Buffer+0
    
    



    doesn't work right.
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-05 03:11
    What Mike said! You forgot to initialize for the first access.
    EmptyLocalBuffer
                           MOVD  ZeroLocal, #Buffer    '''' this was missing!!!! 
                           mov     t0, #8
                           
    ZeroLocal               mov     0-0, Zero
                            add     ZeroLocal, incrDest
                            djnz    t0, #ZeroLocal
                            
    EmptyLocalBuffer_ret    ret
    
  • hippyhippy Posts: 1,981
    edited 2008-01-05 03:13
    Yes, the Propeller does pipelining. You need a 'nop' or some other instruction in there.
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-05 03:15
    That's why I placed your missing instruction at the top. We tend to forget this from time to time.. But it is all in my Tutorial...
  • Chad GeorgeChad George Posts: 138
    edited 2008-01-05 03:17
    deSilva: Wouldn't the copy into the COG initialize it the 1st time (I was of course only calling it once)

    hippy: I thought I tried putting one in there as I couldn't find a detailed description of the Fetch-Decode-Execute cycle to check on the pipelining.
    that's probably the issue though

    I have a working version now though, thanks.
    Chad
  • Chad GeorgeChad George Posts: 138
    edited 2008-01-05 03:25
    OK. sorry for the hassle everyone. Original version works now. Must have accidentally fixed the real problem [noparse]:)[/noparse]

    At least you validated that I wasn't going crazy and the code should work (assuming proper initialization of course)

    -Chad
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-05 03:33
    Chad George said...
    ...as I couldn't find a detailed description of the Fetch-Decode-Execute cycle to check on the pipelining.
    There is a comprehensive (though tentative) description in deSilva's Machine Language Tutorial
  • Fred HawkinsFred Hawkins Posts: 997
    edited 2008-01-05 07:48
    Interesting.
    A simple data array doubles in·memory use·because the calling·code assumes·the array is zero'ed.
    Coming at it from another direction, if you cut the need to only·7 longs in buffer you could just unroll the loop and forget the djnz.
    At 8 longs, it's a wash.


    EmptyLocalBuffer
    1)······················ MOVD· ZeroLocal, #Buffer··· '''' this was missing!!!!
    2)······················ mov···· t0, #8
    ······················
    3) ZeroLocal·············· mov···· 0-0, Zero
    4)······················· add···· ZeroLocal, incrDest
    5)······················· djnz··· t0, #ZeroLocal
    ·······················
    6) EmptyLocalBuffer_ret··· ret
    7) Zero······ long $00000000
    8) incrDest· long %10_00000000
    Buffer···· long 0,0,0,0,0,0,0,0
    9) t0·········· res 1
    __________________________ alternatively

    1) EmptyLocalBuffer sub Buffer,Buffer
    2)························· sub Buffer+1,Buffer+1
    3)························· sub Buffer+2,Buffer+2
    4)························· sub Buffer+3,Buffer+3
    5)························· sub Buffer+4,Buffer+4
    6)························· sub Buffer+5,Buffer+5
    7)························· sub Buffer+6,Buffer+6
    8)························· sub Buffer+7,Buffer+7
    9) EmptyLocalBuffer_ret··· ret
    Buffer···· long 0,0,0,0,0,0,0,0


    Post Edited (Fred Hawkins) : 1/5/2008 8:09:40 AM GMT
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-05 12:14
    Sophistic as Fred's posting is (the "pseudoconstants" ZERO and "INCRDEST" are generally used for more purposes, and an intermeditely unused cell as T0 should be readily available as well) it shows that you ALWAYS should consider alternatives. Even small loops tend to absorb more memory than you expect when coming from more traditional controllers, this is the overhead for code modification, but also the RISC characteristic of all-32-bit instructions. When you have grown up that POP, PUSH, and RET are one byte only you have your surprises.

    I like the SUBs smile.gif
    NAND, XOR, and SHL/SHR #31 will work as well... In fact that was the first lesson in 8080 programming ("How to clear a register" smile.gif )
  • CardboardGuruCardboardGuru Posts: 443
    edited 2008-01-05 15:05
    deSilva said...
    Sophistic as Fred's posting is (the "pseudoconstants" ZERO and "INCRDEST" are generally used for more purposes

    I would have thought most people would be using #0 for zero most of the time. I think there's the odd case where you can't use an immediate operand, and might need a zero in a memory location, but i wouldn't have thought most routines would need it.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    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
  • deSilvadeSilva Posts: 2,967
    edited 2008-01-05 17:48
    It is needed more often than you would think.
    INA, PHSx, or CNT (or even PAR) cannot be used as "dest" operand. So they must be at "scr". WAITPxx is a similar case when you wait for low lines, etc. etc.
  • Fred HawkinsFred Hawkins Posts: 997
    edited 2008-01-05 23:55
    deSilva said...
    Sophistic as Fred's posting is (the "pseudoconstants" ZERO and "INCRDEST" are generally used for more purposes, and an intermeditely unused cell as T0 should be readily available as well) it shows that you ALWAYS should consider alternatives. Even small loops tend to absorb more memory than you expect when coming from more traditional controllers, this is the overhead for code modification, but also the RISC characteristic of all-32-bit instructions. When you have grown up that POP, PUSH, and RET are one byte only you have your surprises.

    I like the SUBs smile.gif
    NAND, XOR, and SHL/SHR #31 will work as well... In fact that was the first lesson in 8080 programming ("How to clear a register" smile.gif )

    I feign ignorance of your fakeconstants, and submit this 11% improvement:

    EmptyLocalBuffer
    1)······················ MOVD· ZeroLocal, #Buffer··· '''' this was missing!!!!
    2)······················ mov···· t0, #8
    ······················
    3) ZeroLocal··········sub Buffer, Buffer
    4)······················· add···· ZeroLocal, incrs
    5)······················· djnz··· t0, #ZeroLocal
    ·······················
    6) EmptyLocalBuffer_ret··· ret
    7) incrs· long %10_00000001
    Buffer···· long 0,0,0,0,0,0,0,0
    8) t0·········· res 1
Sign In or Register to comment.