Forum: Compiler & IDEs Inline Assembler _crc_ccitt_update von util/crc16.h nach Assembler


von Stefan (Gast)


Lesenswert?

Servus!

Folgende Funktion is beim WinAVR als Inline Assembler dabei.

Da ich ein Ende der Funkbrücke von Benedikt K. mit Assembler 
programmieren möchte, muss ich auch die CRC vom WinAVR für Assembler 
umschreiben.
Sie schaut so aus:
1
static __inline__ uint16_t _crc_ccitt_update (uint16_t __crc, uint8_t __data)
2
{
3
    uint16_t __ret;
4
5
    __asm__ __volatile__ (
6
        "eor    %A0,%1"          "\n\t"
7
8
        "mov    __tmp_reg__,%A0" "\n\t"
9
        "swap   %A0"             "\n\t"
10
        "andi   %A0,0xf0"        "\n\t"
11
        "eor    %A0,__tmp_reg__" "\n\t"
12
13
        "mov    __tmp_reg__,%B0" "\n\t"
14
15
        "mov    %B0,%A0"         "\n\t"
16
17
        "swap   %A0"             "\n\t"
18
        "andi   %A0,0x0f"        "\n\t"
19
        "eor    __tmp_reg__,%A0" "\n\t"
20
21
        "lsr    %A0"             "\n\t"
22
        "eor    %B0,%A0"         "\n\t"
23
24
        "eor    %A0,%B0"         "\n\t"
25
        "lsl    %A0"             "\n\t"
26
        "lsl    %A0"             "\n\t"
27
        "lsl    %A0"             "\n\t"
28
        "eor    %A0,__tmp_reg__"
29
30
        : "=d" (__ret)
31
        : "r" (__data), "0" (__crc)
32
        : "r0"
33
    );
34
    return __ret;
35
}

Ich hab sie jetzt so umgeschrieben:
1
.def wl = r0
2
.def crc0 = r16
3
.def crc1 = r17
4
5
6
 eor  crc0, XL
7
 mov  wl, crc0
8
 swap  crc0
9
 andi  crc0, 0xF0
10
 eor  crc0, wl
11
 mov  wl, crc1
12
 mov  crc1, crc0
13
 swap  crc0
14
 andi  crc0, 0x0F
15
 eor  wl, crc0
16
 lsr  crc0
17
 eor  crc1, crc0
18
 eor  crc0, crc1
19
 lsl  crc0
20
 lsl  crc0
21
 lsl  crc0
22
 eor  crc0, wl

Dass das _tmp_reg_ gleich r0 is und worin die Parameter stehn is mir 
schon klar, doch wo steht der Rückgabewert __ret dann drinnen? In 
crc1:crc0?

MfG

Stefan

von Stefan (Gast)


Lesenswert?

Ja, hat sich erledigt. Es ist so, dass das Ergebnis in crc1:crc0 
steht...
Die Routine vom ELM-Chan unten, die ich zuerst verwendete liefert ein 
andres Ergebnis und braucht mehr Takte, obwohl auch CCITT dabeisteht. 
Vielleicht hab ich sie auch nur falsch angewendet, aber es passt jetzt.
1
;-----------------------------------------------;
2
; Generate/Check CRC(-CCITT)
3
;
4
; Register Variables
5
;  Call:  crc[1:0]    = CRC working register
6
;         src         = Source data to be checked
7
;         lc,tmp[1:0] = <don't care> (high register must be allocated)
8
;
9
;  Result:crc[1:0]    = Updated
10
;         src         = 0
11
;         lc,tmp[1:0] = broken
12
;
13
; Size  = 12 words
14
; Clock = 66..74 cycles (+ret)
15
; Stack = 0 byte
16
;
17
; To generate a CRC:
18
; 1. Clear CRC working register.
19
; 2. Process all data bytes in the block.
20
; 3. Process two bytes of zero.
21
; 4. The CRC will be found in the working register.
22
; 5. Append crc1 and crc0 to the block data.
23
;
24
; To check block:
25
; 1. Clear CRC working register.
26
; 2. Process all data bytes in the block and following CRCs.
27
; 3. The block is correct if the working register is zero.
28
29
30
crc:
31
  ldi  tmp1,0b00010000  ;CRC-CCITT (2^16+2^12+2^5+2^0)
32
  ldi  tmp0,0b00100001  ;/
33
  ldi  lc,8    ; Loop count = 8
34
  lsl  src    ;--- bit processing loop
35
  rol  crc0    ;Shift-in a bit into working reg.
36
  rol  crc1    ;/
37
  brcc  PC+3    ;If pushed out a bit "1", divide it.
38
  eor  crc1,tmp1  ;
39
  eor  crc0,tmp0  ;/
40
  dec  lc    ;Repeat until end of loop
41
  brne  PC-7    ;/
42
  ret
Ok, sie braucht dafür weniger FLASH

Gibt es da einen Unterschied zwischen den beiden, oder sonstige Vor- und 
Nachteile?

MfG

Stefan

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.