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.