Parece que no has comprendido bien el mecanismo de interrupción. Te lo explico un poco mejor:
Imagina que el PIC está ejecutando un programa, ejecutará las líneas de código de forma secuencial, hasta que encuentra un salto a alguna parte del código, por esta razón es que main() debe tener un ciclo infinito, para asegurar que al terminar de ejecutar las líneas de código de main(), el programa comience nuevamente por el principio. Si no se hace así el PIC continuará "ejecutando" código hasta que llegue al final de su espacio de direcciones y se quede zoombie.
Bien, lo anterior explica como funciona un programa cualquiera, si tienes intención de atender periféricos con un programa así, se dice que estás atendiendo al proceso por encuesta, ya que en alguna parte del código preguntarás por el estado de algun registro para en función del resultado ejecutar una acción. Este mecanismo es ineficiente y muchas veces no puede ser utilizado porque hay procesos que duran muy poco en el tiempo y necesitan ser atendidos rápidamente, para ello existen los mecanismos de interrupción.
Cada vez que el PIC ejecuta una instrucción, antes de cargar la que le sigue, primero chequea si se ha producido una interrupción, si es así, entonces mete el Contador de programas (CP) en la pila (el CP apunta a la instrucción que debe ejecutar el procesador en el programa normal), y carga una dirección fija en el CP, en este caso 0x0004h y carga la instrucción que se encuentra en esta dirección. Has entrado en la ISR (Interrupt Service Routine), cuando terminas de ejecutar este código, la última intsrucción tiene que ser retfie, para que el PIC saque de la pila el valor del CP que estaba antes de que se atendiera a la interrupción.
Claro el compilador de C, hace parte del trabajo por tí y te evita tener que fajarte con salvar registros que utilizas dentro de una ISR, pone por tí código para retornar de la interrupción, etc.
La directiva #int_ext le dice el compilador que la función que le sigue en el código es la subrrutina de atención a la interrupción externa. Esto quiere decir que cuando se produzaca esta interrupción se ejecutará el código de esta función y cuando se termine de ejecutar se retorna al punto del programa donde se produjo la interrupción. Cuando se produce una interrupción: ¡NADIE SABE!, lo que si debemos asegurar es que se atienda lo más rápido posible.
Lo otro de trabajar con interrupciones es que la sbrutina de atención debe ser LO MÁS CORTA POSIBLE, eso quiere decir que debemos separar lo esencial del proceso de atención de las cosas que debemos hacer en consecuencia. Por ejemplo una ISR para atender al converor AD, quizás solamente deba leer el dato del resultado, cambiar el canal y dar nuevamente inicio de conversión, el programa principal se encargará de procesar los datos y hacer algo con el resultado de ese procesamiento, no debemos poner todo el código de actuación ante una interrupción en la ISR porque muchas de las cosas que hagamos ante una interrupción no requieren que se actúe de inmediato, aunque si hay que atender las cosas esenciales a la mayor brevedad posible.
En el caso de lo que pretendes hacer la INT_EXT te permite saber que se apretó una tecla, y con eso le indicas al programa principal (el que está dentro de main()) que se apretó la tecla para que sea este código quien actúe en consecuencia. El uso de la Interrupción te permite que no se pierda la pulsación de una tecla, ya que si tu programa está haciendo algo que consume tiempo, es posible que la tecla se apriete y se suelte y tu PIC no se de cuenta, aunque esto es poco probable que ocurra con una tecla, hay procesos que son bastante rápidos y eso puede ocasionar que se pierda información o no se tengan encuenta determinados procesos.
Reinier