Un proyecto en el que estoy trabajando implica una rutina de servicio de interrupción de ciclo preciso. Esta rutina está escrita en el ensamblaje de AVR donde acabo de escribir:
.org oc1aadr
rjmp INTRP
(para configurar el IVT) Y funcionó perfectamente bien. Sin embargo, tuve que usar tanto C como ensamblaje para este proyecto, así que cambié a GCC y, después de buscar algo de documentación, encontré que solo tenía que escribir la rutina con una etiqueta:
TIMER1_COMPA_vect:
Ahora la interrupción está funcionando bien también, pero la cosa es que ahora toma 3 ciclos ingresar al ISR. Al buscar el código del desensamblador, vi que el IVT es así:
+00000000: 940C002A JMP 0x0000002A Jump
+00000002: 940C0047 JMP 0x00000047 Jump
+00000004: 940C0047 JMP 0x00000047 Jump
+00000006: 940C0047 JMP 0x00000047 Jump
+00000008: 940C0047 JMP 0x00000047 Jump
+0000000A: 940C0047 JMP 0x00000047 Jump
+0000000C: 940C0047 JMP 0x00000047 Jump
+0000000E: 940C0049 JMP 0x00000049 Jump
+00000010: 940C0047 JMP 0x00000047 Jump
La instrucción JMP toma 3 ciclos a diferencia de RJMP, que solo toma 2. He intentado escribir:
.org 0x0E
rjmp INTRP
Pero aún así no funcionará, también he intentado escribir (.section .init0) antes de .org, pero aún no tengo efecto. Entonces, ¿hay alguna manera en que pueda cambiar la instrucción a RJMP? Nota: solo la rutina de interrupción se escribe en el ensamblaje.
Para mi segunda pregunta: ¿Hay alguna diferencia en los ciclos de reloj requeridos por una instrucción cuando se usan compiladores / ensambladores diferentes? MI rutina completa toma 3 ciclos menos usando GCC en comparación con el ensamblador AVR. No sé si GCC depende del ensamblador AVR o no, pero ¿existe la posibilidad de que esto suceda? (Lo pregunto en base a la salida del simulador AVR).