Hallo t0b4d,
aus einem Interrupt kannst Du nicht so einfach mit GOTO 'verschwinden', auch nicht mit einem RETURN.
Ein Interrupt muß immer mit RETI (Return from Interrupt) beendet werden, weil mit RETI etwas mehr passiert als mit RETURN.
Bei einem CALL wird die momentane Adresse auf den Stack gelegt und zu dem angegebenen Unterprogramm gesprungen. Jedes Unterprogramm muß mit RETURN abgeschlossen werden, weil damit die Rücksprung-Adresse vom Stack zurück geholt wird und nach der 'CALL-Stelle' weiter gemacht wird.
Bei einem Interrupt geschieht genau das Gleiche; zusätzlich werden weitere Interrupts gesperrt und bei RETI wieder freigegeben.
Wenn Interrupts oder CALLs nicht mit RETI bzw. RETURN abgeschlossen werden, werden immer mehr Rücksprung-Adressen auf dem Stack abgelegt; es kommt zu einem Stack-Überlauf und die Reihenfolge ist durcheinander. Das funktioniert nicht.
Bei einer 'sauberen' Interrupt-Service-Routine brauchst Du Dir überhaupt keine Gedanken über das Hauptprogramm zu machen; der µC macht von alleine an den richtigen Stelle weiter, sofern Du jeden Unterprogramm-Aufruf mit RETURN beendest und es zu keinem Stack-Überlauf kommt.
In der ISR kannst Du an den Interrupt-Flags, die Du teilweise sogar per Programm zurücksetzen mußt, abfragen, wer denn der 'Schuldige' ist und entsprechend verzweigen.
Achtung, die Stack-Tiefe ist auf wenige Rücksprungadressen begrenzt; Du kannst somit nicht 10 CALLs ineinander verschachteln und dann noch Interrupts aktiviert haben.
Informationen aus der ISR kannst Du über FileRegister oder Flags (Bits) an die Hauptrotine übergeben.
Z.B. kannst Du einen neuen Wert in der ISR in einem FileRegister ablegen und ein Flag setzen, daß dem Hauptprogramm mitteilt: es ist ein neuer Wert da. Im Hauptprogramm wird dann der neue Wert ausgelesen und das Flag zurück gesetzt.
Einige Assembler-Beispiele findest Du hier und hier.