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


von Tom M. (tomm) Benutzerseite


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

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

von STK500-Besitzer (Gast)


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.

von Tom M. (tomm) Benutzerseite


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

von Stefan E. (sternst)


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.html#faq_reg_usage

von Tom M. (tomm) Benutzerseite


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!

von (prx) A. K. (prx)


Lesenswert?


von Tom M. (tomm) Benutzerseite


Angehängte Dateien:

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

von /* Kommentator */ (Gast)


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:
1
; mod10:      uint8_t in r24 [0..255]
2
; mod10_exit: mod8(r24) in r24
3
4
mod10:
5
    subi r24, 100   
6
    brcs rest
7
    subi r24, 100
8
    brpl sub10
9
rest: 
10
    subi r24, -100
11
sub10:    
12
    subi r24, 10
13
    brpl sub10
14
    subi r24, -10
15
mod10_exit:
16
    ret

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.