Shop OBEX P1 Docs P2 Docs Learn Events
How Do I Divide in ASM — Parallax Forums

How Do I Divide in ASM

tom90tom90 Posts: 55
edited 2008-02-11 04:45 in Propeller 1
Hey All,

I am trying to add another cog onto some code I wrote for an A/D that will average the values.
I have tried to get started by just adding up five numbers (1, 2, 3, 4, 5) and trying to divide by
five, but have had no luck in figuring out how to divide.

Anybody out there with some advice or a good divide routine?

Thanks
Tom

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-07 20:12
    The "Propeller Guts" document has sample multiply and divide routines in it.
    Here's a thread with a link in the first message: http://forums.parallax.com/showthread.php?p=572669
  • Nick MuellerNick Mueller Posts: 815
    edited 2008-02-07 20:16
    > nd trying to divide by five, but have had no luck in figuring out how to divide.

    The most obvious solution is to sample over powers of two (2, 4, 8, 16, ...)


    Nick

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

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-07 20:26
    Why not read my "Tutorial"???
  • tom90tom90 Posts: 55
    edited 2008-02-07 20:41
    Thanks Mike, that document looks to have some good stuff in it.· However, I was trying something similar to this before and couldn't get it to work.· I tried the code in "propeller guts" and that doesnt seem to be working either.· Here is the code that I am trying to use:

    DAT
                  ORG       0
    divtest       
                  
    :loop         mov       Total, A1
                  add       Total, A2
                  add       Total, A3
                  add       Total, A4
                  add       Total, A5
             
                  shl Total,#15              'get divisor into y[noparse][[/noparse]30..15]
                  mov t,#16              'ready for 16 quotient bits
                  
    :loop1        cmpsub x,Total wc          'if y =< x then subtract it, quotient bit into c
                  rcl x,#1               'rotate c into quotient, shift dividend
                  djnz t,#:loop1          'loop until done
                  
                  wrlong    x, par
                  jmp       #:loop
     
     
    A1      long            %0000_0000_0000_0000_0000_0000_0000_0001
    A2      long            %0000_0000_0000_0000_0000_0000_0000_0010
    A3      long            %0000_0000_0000_0000_0000_0000_0000_0011
    A4      long            %0000_0000_0000_0000_0000_0000_0000_0100
    A5      long            %0000_0000_0000_0000_0000_0000_0000_0101
    
    x       long                
    t       long                
    Total                   res 1
    

    Whats wrong?
    Thanks
    Tom
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-07 20:49
    You've got it backwards. The subroutine calculates x := x / Total which I don't think is what you want.
    Change Total to y and then change x to Total. Then put "mov y,#5" before the "mov t,#16".
  • tom90tom90 Posts: 55
    edited 2008-02-07 21:05
    Thanks Mike
    I changed my code to what you said, and my output is still 0
    Anymore words of wisdom?
    DAT
                  ORG       0
    divtest       
                  
    :loop         mov       Total, A1
                  add       Total, A2
                  add       Total, A3
                  add       Total, A4
                  add       Total, A5
             
                  shl y,#5              'get divisor into y[noparse][[/noparse]30..15]
                  mov t,#16              'ready for 16 quotient bits
                  
    :loop1        cmpsub Total,y wc          'if y =< x then subtract it, quotient bit into c
                  rcl Total,#1               'rotate c into quotient, shift dividend
                  djnz t,#:loop1          'loop until done
                  
                  wrlong    Total, par
                  jmp       #:loop
    A1      long            1'%0000_0000_0000_0000_0000_0000_0000_0001
    A2      long            2'%0000_0000_0000_0000_0000_0000_0000_0010
    A3      long            3'%0000_0000_0000_0000_0000_0000_0000_0011
    A4      long            4'%0000_0000_0000_0000_0000_0000_0000_0100
    A5      long            5'%0000_0000_0000_0000_0000_0000_0000_0101
    
    y       long                
    t       long                
    Total                   res 1
    

    Thanks
    Tom
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-07 21:37
    Instead of "shl y,#5" try "mov y,#5" then "shl y,#15".
  • Chuck McManisChuck McManis Posts: 65
    edited 2008-02-07 21:44
    A couple of things pop out in your code, the statement "shl y, #5" shifts the value of Y left by five bits, since y is not initialized it probably has zero in it to begin with. If you really want the divisor to be in bits 30..15 then you should have
    [noparse][[/noparse]code]
    mov y, #5 ' divisor is 5
    shl y, #16 ' shift it left into high order bits
    [noparse][[/noparse]code]

    The other is that Total will be filling up with bits as you do this but I suspect that may be how the routine works.
  • tom90tom90 Posts: 55
    edited 2008-02-08 19:23
    Hello Again,

    Thanks for all of the help guys, but this still just wont work.

    Are all of my variables defined properly?· I am not exactly sure what should be defined as a long, and should should be defined with [noparse][[/noparse]res 1].

    Any other hints you can give me?

    Thanks Again,

    Tom
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-08 19:44
    Please post the version that doesn't seem to work. Include the Spin code that starts up the cog (that may not be correct).
  • tom90tom90 Posts: 55
    edited 2008-02-08 19:47
    CON
      _clkmode = xtal1 + pll4x                          
      _xinfreq = 5_000_000
    OBJ
        debug : "pc_debug"
    VAR
      long  answer
      
    PUB Main
      debug.start(2_400)     
      cognew(@divtest, @answer)
    repeat
      debug.str(string("Answer "))           'Writes AdcValue to the Screen
      debug.dec(answer)
      debug.str(string("  ")) 
    DAT
                  ORG       0
    divtest       
                  
    :loop         mov       Total, A1
                  add       Total, A2
                  add       Total, A3
                  add       Total, A4
                  add       Total, A5
                  mov y,#5              'get divisor into y[noparse][[/noparse]30..15]
                  shl y,#15      
                  mov t,#16              'ready for 16 quotient bit
    
    :loop1        cmpsub Total,y wc          'if y =< x then subtract it, quotient bit into c
                  rcl Total,#1               'rotate c into quotient, shift dividend
                  djnz t,#:loop1          'loop until done
                 
                  wrlong    Total, par
                  jmp       #:loop
     
    A1      long            1'%0000_0000_0000_0000_0000_0000_0000_0001
    A2      long            2'%0000_0000_0000_0000_0000_0000_0000_0010
    A3      long            3'%0000_0000_0000_0000_0000_0000_0000_0011
    A4      long            4'%0000_0000_0000_0000_0000_0000_0000_0100
    A5      long            5'%0000_0000_0000_0000_0000_0000_0000_0101
    y       long                
    t       long
    Total                   res 1
       
    
  • Nick MuellerNick Mueller Posts: 815
    edited 2008-02-08 19:51
    > Any other hints you can give me?

    I just picked deSilva's example (that he picked from somewhere else) and it worked.
    It's a good strategy -when developing software- to start with snippet, test, verify and understand them- and then integrate them into a whole.


    Nick

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

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
  • tom90tom90 Posts: 55
    edited 2008-02-08 20:20
    Thats the same code that i have posted above and it doesnt work.

    Could you post the code you have working so i can compare the two?



    Thanks

    Tom
  • parskoparsko Posts: 501
    edited 2008-02-08 20:27
    Before you write your value, perform an "and Total,$0000FFFF" where $0000FFFF is actually a long such as "h0000FFFF long $0000FFFF"

    I suspect your remainder is killing you. What results are you actually getting on the debug?

    :loop1        cmpsub Total,y wc          'if y =< x then subtract it, quotient bit into c
                  rcl Total,#1               'rotate c into quotient, shift dividend
                  djnz t,#:loop1          'loop until done
                 
                  and Total,h0000FFFF   <---new line of code to remove the remainder
                  wrlong    Total, par
                  jmp       #:loop
     
    A1      long            1'%0000_0000_0000_0000_0000_0000_0000_0001
    A2      long            2'%0000_0000_0000_0000_0000_0000_0000_0010
    A3      long            3'%0000_0000_0000_0000_0000_0000_0000_0011
    A4      long            4'%0000_0000_0000_0000_0000_0000_0000_0100
    A5      long            5'%0000_0000_0000_0000_0000_0000_0000_0101
    y       long               <---Also, give this guy a value, though I don't think it mattters
    t       long                <-------him too!
    h0000FFFF long $0000FFFF  <----new variable
    Total                   res 1
    
    



    See if that helps

    -Parsko
  • tom90tom90 Posts: 55
    edited 2008-02-08 20:29
    Thanks parsko, I will try this shortly.

    All I keep getting for output is 0.

    Tom
  • tom90tom90 Posts: 55
    edited 2008-02-08 20:36
    Parsko, you are my new favorite person!

    It was the variables y and t not being assinged a value that was doing it.



    Thanks

    Tom
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-08 20:37
    parsko said...

    y       long               <---Also, give this guy a value, though I don't think it mattters
    t       long                <-------him too!
    h0000FFFF long $0000FFFF  <----new variable
    
    


    Oh, yes! It matters terribly smile.gif
    THis is a specific syntax, alligning the label to a specific size. ALL THREE names Y, T, and H0000FFF share the same cell, which is the cause of the problem...

    BTW... Aribas debugger PASD should have helped you all along and out of that problem...
  • parskoparsko Posts: 501
    edited 2008-02-08 20:39
    Thanks, deSilva for confirming (I always give them a value, so I never knew it would mattter). Thanks Tom. I've been knee-deep in math routines this week...

    Also, try removing and adding the "and" reoutine (to remove the remainder) to see the results. They should jump from something that makes sense (like 3), to something that clearly doesn't make sense (like 456,845,239)!

    -Parsko
  • APAP Posts: 24
    edited 2008-02-10 23:50
    What I do: Add 4 or 8 or 16 samples, then divide the resulting sum by shift right by #2, #3, or #4, respectively. Simple, quick, and it works.

    Dean
  • Jim ColemanJim Coleman Posts: 52
    edited 2008-02-11 04:45
    SPAD code for this problem:

    '###################################### SPAD BLOCK 5 ####################
    '##
    Code nop 'Start your assembly language program here! '##

    mov Total,A1
    add Total,A2
    add Total,A3
    add Total,A4
    add Total,A5

    mov dividend,Total
    mov divisor,#5
    call #divide 'Divide Total / 5

    str1 byte "Answer ",0
    mov debugVar,#str1
    call #debugStr 'Send string str1 to the terminal

    mov debugVar,quotient
    call #debugDec 'Send decimal quotient to the terminal

    mov debugVar,#13
    call #debugChar 'Send carriage return to the terminal

    mov debugVar,#4
    call #debugDelay 'Delay 4 quarter seconds or 1 second

    jmp #Code 'Repeat

    A1 long 1
    A2 long 2
    A3 long 3
    A4 long 4
    A5 long 5
    Total long 0

    fit
Sign In or Register to comment.