www.mikrocontroller.net

Forum: Compiler & IDEs Assembler Routinen einbinden (Divison/Modulo 10)


Autor: Tom M. (tomm) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo allerseits


Ich versuche mich gerade dran, zwei Assembler Routinen in ein C Programm 
einzubinden. Compilieren & Linken funktionieren prima.

Leider tun die Assembler Routinen nicht was ich will. Habt ihr mir einen 
Tipp, wo ich mich beim Code vertan habe? Danke. :)


Das ist mein ASM Sourcecode (Zeilennummern aus dem Editor):
  1 #include <avr/io.h>
  2 
  3 .global div10
  4 .global mod10
  5 
  6 .section .text
  7 
  8    ; div10: divide given number by 10
  9    ; using the approximation (n+1)*51 >>9
 10    ; call:     uint8_t in r25
 11    ; return:   uint8_t in r24
 12 
 13 div10:
 14    ldi   r24, 51     ; Faktor laden
 15    inc   r25         ; n+1
 16    mul   r24, r25    ; Produkt in r1:r0
 17    movw  r24, r0     ; Resultat uebertragen
 18    lsr   r25         ; rechts schieben (division durch 2)
 19    mov   r24, r25    ; weitere 8 shifts (divison durch 256)
 20    eor   r25, r25    ; high byte zur Sicherheit loeschen
 21    eor   r1, r1      ; r1 loeschen (soll immer 0 sein)
 22    ret
 23 
 24    ; mod10: return modulo 10 of given number
 25    ; using the approximation (n+1)*51 >>9
 26    ; call:     uint8_t in r25
 27    ; return:   uint8_t in r24
 28 
 29 mod10:
 30    ldi   r24, 51     ; Faktor laden
 31    inc   r25         ; n+1
 32    mul   r24, r25    ; Produkt in r1:r0
 33    dec   r25         ; n wiederherstellen
 34    lsr   r1          ; r1 ist jetzt r1:r0 >> 9
 35    sub   r25, r1     ; r25 ist jetzt modulo 10
 36    mov   r24, r25    ; Ergebnis in r24 bereit stellen
 37    eor   r25, r25    ; high byte zur Sicherheit loeschen
 38    eor   r1, r1      ; r1 loeschen
 39    ret
 40 
 41 .end

Für das C Interface verwende ich dieses Header File mit den Prototypen:
uint8_t  div10( uint8_t divisor );
uint8_t  mod10( uint8_t divisor );

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht es dir darum, die mathematischen Funktionen in C zu benutzen, oder 
allgemein darum, Assembler in C einzubinden?
Für den ersten Teil empfehle ich dir mal das "%" in einer C-Referenz 
nachzuschlagen.
Beim 2. Teil kann ich dir nicht wirklich helfen.
Vielleicht solltest du es mit Inline-Assembler probieren.

Autor: Tom M. (tomm) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STK500-Besitzer schrieb:
> Geht es dir darum, die mathematischen Funktionen in C zu benutzen, oder
> allgemein darum, Assembler in C einzubinden?

Die C Funktionen sind viel schwergewichtiger, deshalb will ich meine 
eigenen, für uint8_t Zahlen, einbinden.

> Beim 2. Teil kann ich dir nicht wirklich helfen.

Schade. :)

> Vielleicht solltest du es mit Inline-Assembler probieren.

Bitte nicht. :)


Schönen Abend & Gruss

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anscheinend erwartest du den übergebenen 8 Bit Parameter in R25. Er ist 
aber in R24.

Abschnitt "Function call convention" hier:
http://www.nongnu.org/avr-libc/user-manual/FAQ.htm...

Autor: Tom M. (tomm) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst schrieb:
> Anscheinend erwartest du den übergebenen 8 Bit Parameter in R25. Er ist
> aber in R24.

Oh... Das wird's sein, hab ich glatt überlesen. Danke!

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Tom M. (tomm) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier mein aktueller Code, der jetzt auch funktioniert. Vielleicht 
hilft's ja dem nächsten, der uint8_t (unsigned char) Parameterübergabe 
machen will. :)

+ Parameterübergabe tut jetzt
+ modulo 10 Code oben war völlig kaputt, tut jetzt auch

Mit der aktuellen Implementation decke ich "nur" den 
Eingabe-Wertebereich 0..254 ab. Für 255 müsste ich noch code hinzufügen.


Gruss
Tom

Autor: /* Kommentator */ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn das Zwischenergebnis (div10) nicht benötigt wird, der Code kompakt 
sein soll, das Ergebnis auch für 0xff stimmen soll und die Zyklenzahl 
keine Rolle spielt:
; mod10:      uint8_t in r24 [0..255]
; mod10_exit: mod8(r24) in r24

mod10:
    subi r24, 100   
    brcs rest
    subi r24, 100
    brpl sub10
rest: 
    subi r24, -100
sub10:    
    subi r24, 10
    brpl sub10
    subi r24, -10
mod10_exit:
    ret

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.