Forum: Mikrocontroller und Digitale Elektronik Inline Assembler


von Florian I. (fbeek)


Lesenswert?

hi leute hab mal ne Frage.
Unzwar würde ich gern in meinem C Programm ein 16x16 Multiplikation 
nutzen und habe mir daher von Atmel dieses Stück Assembler Code geholt:
1
;***************************************************************************
2
;*
3
;* "mpy16u" - 16x16 Bit Unsigned Multiplication
4
;*
5
;* This subroutine multiplies the two 16-bit register variables 
6
;* mp16uH:mp16uL and mc16uH:mc16uL.
7
;* The result is placed in m16u3:m16u2:m16u1:m16u0.
8
;*  
9
;* Number of words  :14 + return
10
;* Number of cycles  :153 + return
11
;* Low registers used  :None
12
;* High registers used  :7 (mp16uL,mp16uH,mc16uL/m16u0,mc16uH/m16u1,m16u2,
13
;*                          m16u3,mcnt16u)  
14
;*
15
;***************************************************************************
16
17
;***** Subroutine Register Variables
18
19
.def  mc16uL  =r16    ;multiplicand low byte
20
.def  mc16uH  =r17    ;multiplicand high byte
21
.def  mp16uL  =r18    ;multiplier low byte
22
.def  mp16uH  =r19    ;multiplier high byte
23
.def  m16u0  =r18    ;result byte 0 (LSB)
24
.def  m16u1  =r19    ;result byte 1
25
.def  m16u2  =r20    ;result byte 2
26
.def  m16u3  =r21    ;result byte 3 (MSB)
27
.def  mcnt16u  =r22    ;loop counter
28
29
;***** Code
30
31
mpy16u:  clr  m16u3    ;clear 2 highest bytes of result
32
  clr  m16u2
33
  ldi  mcnt16u,16  ;init loop counter
34
  lsr  mp16uH
35
  ror  mp16uL
36
37
m16u_1:  brcc  noad8    ;if bit 0 of multiplier set
38
  add  m16u2,mc16uL  ;add multiplicand Low to byte 2 of res
39
  adc  m16u3,mc16uH  ;add multiplicand high to byte 3 of res
40
noad8:  ror  m16u3    ;shift right result byte 3
41
  ror  m16u2    ;rotate right result byte 2
42
  ror  m16u1    ;rotate result byte 1 and multiplier High
43
  ror  m16u0    ;rotate result byte 0 and multiplier Low
44
  dec  mcnt16u    ;decrement loop counter
45
  brne  m16u_1    ;if not done, loop more
46
  ret

meine Frage ist nun wie ich diesen Code in mein Programm einbaue so das 
ich ihn zum beispiel per Multi(x,y) aufrufen kann.Hab keine Ahnung vom 
Assembler.

Gruss Flo

von Sven P. (Gast)


Lesenswert?

Computer --> Internet --> Google --> AVR libc --> User Manual --> 
"Inline Assembler Cookbook"

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Naja, inline assembler dafür ist eigentlich Humbug.  Da er ohnehin
eine Funktion aufrufen können will, wäre eine separate Assemblerdatei
viel sinnvoller.

Mit "ab keine Ahnung vom Assembler" wird man da allerdings so oder so
nicht sehr weit kommen.

http://www.nongnu.org/avr-libc/user-manual/group__asmdemo.html
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage

von Florian I. (fbeek)


Lesenswert?

das Problem is das ich einfach nur ein Funktion für die Multiplikation 
benötige, da ich einen AD Wert in eine Spannung Wandeln möchte.Habe aber 
noch keine in C gefunden

von spess53 (Gast)


Lesenswert?

Hi

Für welchen Controller soll das denn sein? Atmegas haben z.B. einen 
Hardwaremultiplizierer. Dann wäre der Code Unsinn. Ansonsten musst du 
dich mal informieren, wie in C Variablen übergeben werden (Register, 
Stackframe,...).

MfG Spess

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Florian Idb wrote:
> das Problem is das ich einfach nur ein Funktion für die Multiplikation
> benötige, da ich einen AD Wert in eine Spannung Wandeln möchte.Habe aber
> noch keine in C gefunden

Aber C kannst du, ja?  Dann weißt du auch, dass man mit einem Stern
als Operator multipliziert, oder?

von Sven P. (Gast)


Lesenswert?

Tuts die Multiplikationsroutine aus der LIBC denn nicht?

von Florian I. (fbeek)


Lesenswert?

Das mit dem Stern ist klar aber wenn ich 678*2560 rechne spuckt der 
Werte raus mit 15 stellen das kann nicht sein. Es handelt sich um einen 
Atmega 8.

von Tom (Gast)


Lesenswert?

@fbeek,

dann poste doch mal deinen C Sourcecode und ich schaue solange ob ich 
noch Popcorn finde.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Florian Idb wrote:

> Das mit dem Stern ist klar aber wenn ich 678*2560 rechne spuckt der
> Werte raus mit 15 stellen das kann nicht sein.

Doch, das ist so.  Bevor du hier mit Assembler losschlagen willst,
mit dem du nach deiner Aussage gar nicht umgehen kannst, mach dir
erstmal Gedanken um C und um die Wertebereiche von Zahlen.

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.