Если рассматриваемым компилятором является mspgcc, он должен выпустить список ассемблера скомпилированной программы вместе с двоичным / шестнадцатеричным файлом. Для других компиляторов могут потребоваться дополнительные флаги компилятора. Или, может быть, даже отдельный дизассемблер работает на двоичном.
Это место, где искать объяснения.
Из-за оптимизации компилятора фактический код, представляемый процессору, может не иметь большого сходства с исходным кодом C (но обычно выполняет ту же работу).
Выполнение нескольких инструкций на ассемблере, представляющих неисправный код, должно выявить причину проблемы.
Я предполагаю, что компилятор каким-то образом оптимизирует все вычисления, так как определенная константа является известной частью во время компиляции.
255 * x можно оптимизировать до x << 8-x (что быстрее и меньше)
Возможно, что-то не так с оптимизированным кодом ассемблера. </p>
Я потратил время на компиляцию обеих версий в моей системе. При активной оптимизации mspgcc создает следующий код:
#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
Как мы видим, компилятор напрямую вычисляет результат от 255 * 3 до -3 (0xfffd). И здесь проблема. Каким-то образом 255 интерпретируется как 8-разрядный со знаком -1 вместо 16-разрядного без знака 255. Или он сначала анализируется до 8 бит, а затем расширяется до 16 бит. или что угодно.
Обсуждение этой темы уже началось в списке рассылки mspgcc.