Forum: Compiler & IDEs 24 bit in 32 bit signed


von hahgeh (Gast)


Lesenswert?

Hallo,
gibt es eine einfachere Möglichkeit einen 24 bit signed Wert, der von 
einer Peripherie gelesen wird in einen 32 bit signed Wert umwandelt, 
damit man normale Rechenoperationen und Vergleiche auch mit negativen 
Zahlen ausführen kann?
Ich mache es bisher immer so:

long int funktion(){
  long int value;
  value=Read24();
  if((value & 0x00800000)) value |= 0xFF000000;
  return value;
}

Bei der umgekehrten Variante kann man ja einfach die 8 höchstwertigsten 
Bit weglassen.

von Hans-jürgen H. (hjherbert) Benutzerseite


Lesenswert?

Die Abfrage mit >= erzeugt weniger Code, wie das Beispiel hier zeigt.
Und wenn die Variable local, statt wie bei mir global ist, dann noch 
weniger


240:      if((value & 0x00800000)) value |= 0xFF000000;
+000002AC:   01DC        MOVW    R26,R24          Copy register pair
+000002AD:   01CB        MOVW    R24,R22          Copy register pair
+000002AE:   E167        LDI     R22,0x17         Load immediate
+000002AF:   95B6        LSR     R27              Logical shift right
+000002B0:   95A7        ROR     R26              Rotate right through 
carry
+000002B1:   9597        ROR     R25              Rotate right through 
carry
+000002B2:   9587        ROR     R24              Rotate right through 
carry
+000002B3:   956A        DEC     R22              Decrement
+000002B4:   F7D1        BRNE    PC-0x05          Branch if not equal
+000002B5:   7081        ANDI    R24,0x01         Logical AND with 
immediate
+000002B6:   7090        ANDI    R25,0x00         Logical AND with 
immediate
+000002B7:   70A0        ANDI    R26,0x00         Logical AND with 
immediate
+000002B8:   70B0        ANDI    R27,0x00         Logical AND with 
immediate
+000002B9:   2388        TST     R24              Test for Zero or Minus
+000002BA:   F049        BREQ    PC+0x0A          Branch if equal
+000002BB:   6F5F        ORI     R21,0xFF         Logical OR with 
immediate
+000002BC:   93200060    STS     0x0060,R18       Store direct to data 
space
+000002BE:   93300061    STS     0x0061,R19       Store direct to data 
space
+000002C0:   93400062    STS     0x0062,R20       Store direct to data 
space
+000002C2:   93500063    STS     0x0063,R21       Store direct to data 
space



243:      if((value >= 0x00800000)) value |= 0xFF000000;
+000002D1:   3060        CPI     R22,0x00         Compare with immediate
+000002D2:   E020        LDI     R18,0x00         Load immediate
+000002D3:   0772        CPC     R23,R18          Compare with carry
+000002D4:   E820        LDI     R18,0x80         Load immediate
+000002D5:   0782        CPC     R24,R18          Compare with carry
+000002D6:   E020        LDI     R18,0x00         Load immediate
+000002D7:   0792        CPC     R25,R18          Compare with carry
+000002D8:   F048        BRCS    PC+0x0A          Branch if carry set
+000002D9:   6F9F        ORI     R25,0xFF         Logical OR with 
immediate
+000002DA:   93600060    STS     0x0060,R22       Store direct to data 
space
+000002DC:   93700061    STS     0x0061,R23       Store direct to data 
space
+000002DE:   93800062    STS     0x0062,R24       Store direct to data 
space
+000002E0:   93900063    STS     0x0063,R25       Store direct to data 
space

von Peter D. (peda)


Lesenswert?

Hans-jürgen Herbert wrote:
> Die Abfrage mit >= erzeugt weniger Code, wie das Beispiel hier zeigt.


Hää ?

Also weniger als 2 words geht ja wohl nicht:
1
long int funktion(){
2
  long int value;
3
  value=Read24();
4
     a0c:       f4 df           rcall   .-24            ; 0x9f6 <Read24>
5
  if((value & 0x00800000)) value |= 0xFF000000;
6
     a0e:       87 fd           sbrc    r24, 7
7
     a10:       9f 6f           ori     r25, 0xFF       ; 255
8
  return value;
9
}
10
     a12:       08 95           ret

Schalte mal Optimierung -Os ein.


Peter

von hahgeh (Gast)


Lesenswert?

Komisch bei mir ist es genau umgekehrt :)
sogar noch weniger liegt vielleicht an der Optimierung.
Aber danke nochmal für den Denkanstoß, wie man das Ergebnis 
kontrollieren kann.

if((value & 0x00800000)) value |= 0xFF000000;
     570:  80 91 81 00   lds  r24, 0x0081
     574:  90 91 82 00   lds  r25, 0x0082
     578:  a0 91 83 00   lds  r26, 0x0083
     57c:  b0 91 84 00   lds  r27, 0x0084
     580:  a7 ff         sbrs  r26, 7
     582:  09 c0         rjmp  .+18       ; 0x596
     584:  bf 6f         ori  r27, 0xFF  ; 255
     586:  80 93 81 00   sts  0x0081, r24
     58a:  90 93 82 00   sts  0x0082, r25
     58e:  a0 93 83 00   sts  0x0083, r26
     592:  b0 93 84 00   sts  0x0084, r27

UND

if((value >= 0x00800000)) value |= 0xFF000000;
     570:  80 91 81 00   lds  r24, 0x0081
     574:  90 91 82 00   lds  r25, 0x0082
     578:  a0 91 83 00   lds  r26, 0x0083
     57c:  b0 91 84 00   lds  r27, 0x0084
     580:  80 30         cpi  r24, 0x00  ; 0
     582:  20 e0         ldi  r18, 0x00  ; 0
     584:  92 07         cpc  r25, r18
     586:  20 e8         ldi  r18, 0x80  ; 128
     588:  a2 07         cpc  r26, r18
     58a:  20 e0         ldi  r18, 0x00  ; 0
     58c:  b2 07         cpc  r27, r18
     58e:  4c f0         brlt  .+18       ; 0x5a2
     590:  bf 6f         ori  r27, 0xFF  ; 255
     592:  80 93 81 00   sts  0x0081, r24
     596:  90 93 82 00   sts  0x0082, r25
     59a:  a0 93 83 00   sts  0x0083, r26
     59e:  b0 93 84 00   sts  0x0084, r27

von hahgeh (Gast)


Lesenswert?

Oh das von Peter hatte ich noch nicht gelesen.

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


Lesenswert?

> liegt vielleicht an der Optimierung.

Oder vielmehr an der fehlenden solchen?  Dann brauchst du dir aber auch
um die Codegröße keine Gedanken zu machen...  Ich komme auf gleiches
Ergebnis wie Peter.

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.