Fehler im Atmel AVR AN200.ASM?

#558955
Lesenswert?

Hallo,

ich habe mir ein AN von Atmel durchgeschaut und glaube einen Fehler 
gefunden zu haben, vielleicht kann sichs mal jemand anschauen der sich 
mit ASM auskennt. Und zwar geht es um eine 16/16bit unsigned 
Rechenroutine nur finde ich darin leider nichts vom Ergebniss. Es werden 
zwar extra 2 Register(dres18uL und dres18uH) fürs Ergebniss definiert, 
diese bleiben aber ungenutzt. Eigentlich kann ich mir nicht vorstellen 
das Atmel da so geschludert hat aber vielleicht habe ich auch etwas 
übersehen. Da der Quelltext nicht ganz so lange ist hänge ich ihn mal 
etwas gekürzt direkt dran. Könnte es vielelicht sein das das Ergebniss 
in drem16uL und drem16uH steht und noch in die dafür gedachten Register 
kopiert werden muss?

;********************************************************************
;* "div16u" - 16/16 Bit Unsigned Division
;* "This subroutine divides the two 16-bit numbers
;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor).
;* "The result is placed in "dres16uH:dres16uL" and the remainder in
;* "drem16uH:drem16uL".
;********************************************************************
;***** Divide Two Unsigned 16-Bit Numbers (50,000/60,000)
ldi  dd16uL,low(50000)
ldi  dd16uH,high(50000)
ldi  dv16uL,low(60000)
ldi  dv16uH,high(60000)
rcall  div16u    ;result:  $0000 (0)
      ;remainder:  $c350 (50,000)
.def  drem16uL=r14
.def  drem16uH=r15
.def  dres16uL=r16
.def  dres16uH=r17
.def  dd16uL  =r16
.def  dd16uH  =r17
.def  dv16uL  =r18
.def  dv16uH  =r19
.def  dcnt16u  =r20

div16u:  clr  drem16uL  ;clear remainder Low byte
  sub  drem16uH,drem16uH;clear remainder High byte and carry
  ldi  dcnt16u,17  ;init loop counter
d16u_1:  rol  dd16uL    ;shift left dividend
  rol  dd16uH
  dec  dcnt16u    ;decrement counter
  brne  d16u_2    ;if done
  ret      ;    return
d16u_2:  rol  drem16uL  ;shift dividend into remainder
  rol  drem16uH
  sub  drem16uL,dv16uL  ;remainder = remainder - divisor
  sbc  drem16uH,dv16uH  ;
  brcc  d16u_3    ;if result negative
  add  drem16uL,dv16uL  ;    restore remainder
  adc  drem16uH,dv16uH
  clc      ;    clear carry to be shifted into result
  rjmp  d16u_1    ;else
d16u_3:  sec      ;    set carry to be shifted into result
  rjmp  d16u_1
Gast #559115
Lesenswert?

Hallo,

die habe ich gerade letztens genutzt, die Registerbezeichnungen muß man 
wirklich 3x lesen, damit man versteht, was wo landet...

Ansonsten macht die Routine genau, was sie soll.

Gruß aus Berlin
Michael

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren