Shop OBEX P1 Docs P2 Docs Learn Events
MOVD instruction bug? — Parallax Forums

MOVD instruction bug?

ozpropdevozpropdev Posts: 2,791
edited 2007-02-07 11:09 in Propeller 1
Hi guys

I beleive I have discovered a bug with the MOVD instruction. My application like most others requires the passing of pointers from one cog (running SPIN code) to another (running Propeller assembly code). Basically i have an array containg pointers to all the varaibles i wish to access.

The first pointer is to a variable that contains the number of pointers to follow.
This seems simple enough using a loop implementing self modifying code to sequentially retreive the pointers and place them in COG ram.

start·· mov·fx,par··'get pointer to my array
········ rdlong· ax,fx··'get pointer to number of entries
········ rdlong· cx,ax··'get number of entries
······· ·mov···· bx,#pointer0·'set start of cog ram storage area
again· movd··· zzz,bx··'set destination··'
zzz···· rdlong· 0,fx··'read/store pointer
········ add···· bx,#1··'increment destination
········ add···· fx,#4··'adjust pointrer
········ djnz··· cx,#again·'repeat (cx) times
········ jmp·#somewhere_else
.
.
ax·········res·1
bx········ res·1
cx········ res·1
fx········· res·1
poinrer0· res·1
poinrer1· res·1
poinrer2· res·1
.
.
poinrer9· res·1

Not a big program as you can see but it failed!
Further investigation revealed the first RDLONG at address ZZZ returned a LONG from an incorrect address. All subsequent RDLONG operations worked
fine. Extensive testing of this program showed no change in outcome regardless of pointer addresses or cog ram origin. Even using a different cog
had no effect.

The bug seems to be related to modifying code that is the next instruction to be processed. Simply placing a NOP instruction between the MOVD and RDLONG instructions fixed the problem!

Any ideas out there?
·

Comments

  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-02-07 09:44
    The issue is you didnt place an instruction between MOVD and it's target instruction. Because the next instruction is fetched before the results of the previous instruction are written you need to have an intervening instruction.

    The way I do this without having to insert a NOP is to place the MOVD after the target instruction, so you would place the MOVD immediately before the DJNZ, then insert·an intialization MOVD above your loop where there is at least 1 instruction·in between it and the loop. This way you dont have to waste an extra·4 cycles in each iteration and it consumes the same amount of space as the NOP technique. Ive demonstrated this in the following code, the bold lines signify the changes.
    start   mov fx,par  'get pointer to my array
    [b]       mov     bx,#pointer0 'set start of cog ram storage area
    [/b][b]       movd    again,bx[/b]
            rdlong  ax,fx  'get pointer to number of entries
            rdlong  cx,ax  'get number of entries
    again   rdlong  0,fx  'read/store pointer
            add     bx,#1  'increment destination
            add     fx,#4  'adjust pointrer
    [b]       movd    again,bx  'set destination  '
    [/b]        djnz    cx,#again 'repeat (cx) times
            jmp #somewhere_else
    .
    .
    ax         res 1
    bx         res 1
    cx         res 1
    fx          res 1
    poinrer0  res 1
    poinrer1  res 1
    poinrer2  res 1
    .
    .
    poinrer9  res 1
    
    

    Check out the Tricks & Traps sticky thread, it covers this and many other "gotchas" commonly encountered.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 2/7/2007 10:00:38 AM GMT
  • ozpropdevozpropdev Posts: 2,791
    edited 2007-02-07 11:09
    Thanks Paul for your quick response.
    I must of missed that bit in the tricks and traps document... Oops!
Sign In or Register to comment.