...Sinceramente no entiendo por que imaginan que pueden escribir mejores programas en assembler que lo que podría traducir un compilador C ajustado por especialistas y con años de desarrollo encima...
Eso no es cierto, los compiladores de C generan un código lo suficientemente bueno como para que no valga la pena usar assembler, pero los "especialistas y con años de desarrollo encima" se calientan hasta ahí.
Un compilador de C te genera un buen código en las operaciones arimético-lógicas, en las comparaciones/switch, te saca el código muerto, te optimiza el codigo repetido en los bucles, te optimiza la inicialización de variables...
Se puede pensar: Que más se puede pedir? -->
Que terminen la optimización.
El código generado necesita siempre una pasada más. No tengo idea por qué, pero no la hacen o la hacen para el orto.
Unas optimizaciones son "limpiar" el código escrito por nosotros. Es decir, instrucciones redundantes que se dejan por una mejor legibilidad o porque se está sacando diferentes variantes con mínimas modificaciones del fuente.
Es decir, porciones sueltas que deberíamos haber corregido nosotros son "limpiadas" en lo generado.
Como ejemplo (con CCS) :
- Si hay una rutina que nunca es llamada, el compilador debe eliminarla del código si se activa la optimización. --> Pero esté activada o no, la elimina igual.
- Si hay una variable local que se asigna y no se usa, el compilador debe eliminarla --> No la elimina pero te avisa

.
- Si una variable local se usa inútilmente como registro intermedio --> el compilador debe corregirlo.
Es decir, si tengo
Código:
void test(){
int8 aux8 ;
aux8 = Var1 ;
Var2 = aux8 ;
}
debería generarse directamente el código correpondiente a Var2=Var1.
Otros compiladores lo hacen, CCS no.
Las otras optimizaciones son relativas al código generado, en CCS no encuentro mayores objeciones salvo que le falta una pasada.
Durante operaciones aritméticas casi siempre es necesario la creación de variables auxiliares, pero después es necesario un análisis mas para eliminar las que no hacen falta.
Si tengo algo así :
con A16,B16 de 16 bit y C8 de 8 bit
CCS me genera esto (#opt 9):
Código:
MOVF C8,W
IORWF B16_low,W
MOVWF Aux8 <<--
MOVF Aux8,W <<-- WTF !
ANDWF A16_low,F
MOVF B16_high,W
ANDWF A16_high,F
Las direcciones de las variables las reemplacé por el nombre por legibilidad

Se está usando inútilmente una variable auxiliar,
si se suprimen esas dos líneas anda igual
Por suerte, esos defectos solamente puede importar corregirlos en un servicio de interrupción, y solamente si se trata de un servicio de alta velocidad donde interesa que dure el menor tiempo posible.
No se por qué, pero la asignación inútil de variables auxiliares es un pifio bastante común. Será difícil de analizar

El único compilador que pude verificar que
optimizaba de verdad es el de Borland version 4, pero solamente en 32bit. Tanto las anteriores como las posteriores
nada que ver.