Wenn es sich bei dem betreffenden Compiler um den mspgcc handelt, sollte er ein Assembler-Listing des kompilierten Programms zusammen mit der Binär-/Hex-Datei ausgeben. Andere Compiler benötigen dazu möglicherweise zusätzliche Compiler-Flags. Oder vielleicht sogar einen separaten Disassembler, der auf die Binärdatei angewendet wird.
Hier ist der richtige Ort, um nach einer Erklärung zu suchen. Aufgrund von Compiler-Optimierungen hat der tatsächliche Code, der dem Prozessor präsentiert wird, möglicherweise nicht viel Ähnlichkeit mit dem ursprünglichen C-Code (erfüllt aber normalerweise die gleiche Aufgabe).
Wenn Sie die wenigen Assembler-Anweisungen durchgehen, die den fehlerhaften Code darstellen, sollten Sie die Ursache des Problems herausfinden.
Ich vermute, dass der Compiler die gesamte Berechnung irgendwie optimiert, da die definierte Konstante zur Kompilierungszeit ein bekannter Teil ist. 255*x könnte zu x<<8-x optimiert werden (was schneller und kleiner ist). Vielleicht läuft etwas mit dem optimierten Assembler-Code schief.
Ich habe mir die Zeit genommen, beide Versionen auf meinem System zu kompilieren. Mit aktiver Optimierung erzeugt der mspgcc den folgenden Code:
#define PRR_SCALE 255
uint8_t a = 3;
uint8_t b = 4;
uint8_t prr;
prr = (PRR_SCALE * a) / b;
40ce: 3c 40 fd ff mov #-3, r12 ;#0xfffd
40d2: 2a 42 mov #4, r10 ;r2 As==10
40d4: b0 12 fa 6f call __divmodhi4 ;#0x6ffa
40d8: 0f 4c mov r12, r15 ;
printf("prr: %u\n", prr);
40da: 7f f3 and.b #-1, r15 ;r3 As==11
40dc: 0f 12 push r15 ;
40de: 30 12 c0 40 push #16576 ;#0x40c0
40e2: b0 12 9c 67 call printf ;#0x679c
40e6: 21 52 add #4, r1 ;r2 As==10
Wie wir sehen können, berechnet der Compiler das Ergebnis von 255*3 direkt zu -3 (0xfffd). Und hier liegt das Problem. Irgendwie wird die 255 als -1 vorzeichenbehaftetes 8-Bit anstelle von 255 vorzeichenlosen 16-Bit interpretiert. Oder es wird zuerst in 8 Bit geparst und dann auf 16 Bit vorzeichenerweitert oder was auch immer.
Eine Diskussion zu diesem Thema wurde bereits auf der Mailingliste mspgcc gestartet.