Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

division of two signed16 bit numbers

Status
Not open for further replies.

shomikc

Member level 4
Member level 4
Joined
Apr 19, 2013
Messages
71
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,953
Hi. I am trying to learn Atmel AVR microcontroller assembly programming.

I am trying to do the division of two signed 16 bit numbers and I have used the code from the AVR200 webpage but when I rum the program it does not go the quotient registers at all. I have no idea what is going on. Please can anyone help. The code I have used is here. And also when the program returns it does not go to the forever loop but instead it goes to start.


Code:
.def      d16s      =   r13        ;    sign register
.def      drem16sL  =   r22        ;    remainder low byte
.def      drem16sH  =   r23        ;    remainder high byte
.def      dquo16sL  =   r24        ;    quotient low byte
.def      dquo16sH  =   r25        ;    quotient high byte
.def      dd16sL    =   r26        ;    dividend low byte
.def      dd16sH    =   r27        ;    dividend high byte
.def      dv16sL    =   r18        ;    divisor low byte
.def      dv16sH    =   r19        ;    divisor high byte
.def      dcnt16s   =   r20        ;    loop counter

start:
           ldi      dd16sL,low(00)
           ldi      dd16sH,high(10)

           ldi      dv16sL,low(00)
           ldi      dv16sH,high(10)
           rcall    div16s           ;    result:    $f752 (-2222)
                                     ;    remainder:    $0002 (2)

forever:   rjmp    forever


;***** Code

div16s:    mov   d16s,dd16sH     ;    move dividend High to sign register
               eor   d16s,dv16sH     ;    xor divisor High with sign register
               sbrs  dd16sH,7        ;   if MSB in dividend set
               rjmp  d16s_1
               com   dd16sH                       ;    change sign of dividend
               com   dd16sL
               subi  dd16sL,low(-1)
               sbci  dd16sL,high(-1)
d16s_1:    sbrs  dv16sH,7        ;     if MSB in divisor set
              rjmp  d16s_2
               com   dv16sH          ;     change sign of divisor
               com   dv16sL
               subi  dv16sL,low(-1)
               sbci  dv16sH,high(-1)
d16s_2:    clr   drem16sL        ;     clear remainder Low byte
               sub   drem16sH,drem16sH  ;     clear remainder High byte and carry
                ldi   dcnt16s,17      ;      init loop counter

d16s_3:    rol   dd16sL          ;      shift left dividend
           rol   dd16sH
           dec   dcnt16s         ;      decrement counter
           brne  d16s_5          ;      if done
           sbrs  d16s,7          ;      if MSB in sign register set
           rjmp  d16s_4
           com   dquo16sH        ;      change sign of result
           com   dquo16sL
           subi  dquo16sL,low(-1)
           sbci  dquo16sH,high(-1)
d16s_4:    ret                    ;    return
d16s_5:    rol   drem16sL         ;    shift dividend into remainder
                rol   drem16sH
               sub   drem16sL,dv16sL  ;    remainder = remainder - divisor
                sbc   drem16sH,dv16sH  ;
               brcc  d16s_6           ;      if result negative
                add   drem16sL,dv16sL  ;    restore remainder
               adc   drem16sH,dv16sH
               clc                   ;    clear carry to be shifted into result
               rjmp  d16s_3          ;    else
d16s_6:    sec                   ;    set carry to be shifted into result
                rjmp        d16s_3
 

I’m not really that familiar with the AVR, but are you running a debugger? If so, you should be able to trace your code. If you don’t have a debugger or simulator, get one.
 
Hi,


it does not go to the forever loop but instead it goes to start.
* is the power supply stable
* is the stack pointer correctly initialized
* is the watchdog switched OFF?

****
Simple debugging method to see what's going on:
* use port outputs and output unique patterns at several places in your code. Check the states with LEDs or scope.
A scope gives better information, because you see very short pulses and you can measure the timing.

Klaus
 
Do you actually want to load all zero to the registers, e.g. high(10)? Which result do you expect for 0/0?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top