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.
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
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
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
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.