Power On Reset (bzw jeder Reset) ist genau genommen kein Interrupt. Wenn der Reset freigegeben wird, werden (fast) alle I/O-Register initialisiert, ebenso der Programcounter.
Wenn die Bootrst-Fuse aktiviert ist aber nicht auf 0x0000.
Ebenso können die Interruptvektoren verschoben werden, unabhängig von Bootrst.
Jede Interruptquelle ist mit einer festen Adresse "verbunden" - ist der Interrupt selbst scharf, getriggert und I in SREG gesetzt, wird der laufende Befehl beendet, und dann automatisch I in SREG gelöscht, die Rücksprungadresse auf den Stack gepusht (2 Bytes) und die Interrupt-Adresse in den Programcounter geladen. Sind vier Takte. Als nächstes wird also das ausgeführt, was in der IVT steht. Das muß nicht unbedingt ein Sprung in eine ISR sein, meist ist dort aber nicht genug Platz (je nachdem, welche IRQs Du verwendest, und wie kurz die ISR ist aber vielleicht doch).
Es geht mir einfach darum ob es Speicher in Anspruch nimmt oder nicht,
Wenn Du vom Reseteinsprung irgendwo hinter die IVT ("IntVectorsSize") springst, wird der Code in der IVT selbst nur dann ausgeführt, wenn er angesprungen wird. Entweder durch einen (von Dir) aktivierten IRQ, oder durch einen (von Dir) programmierten Sprung.
Sonst ist der Code dort … verschwendet. Strenggenommen kannst Du dort noch Konstanten ablegen, die irgendwo anders mit LPM geladen werden sollen.
Auf der anderen Seite stellt sich die Frage, ob Dir genau diese paar Words Programmspeicher am Ende wirklich fehlen.
Eher kann es notwendig sein, eine ISR dort vorn zu platzieren - wegen der Reaktionszeit eines Interruptes (wie gesagt: nach vier Takten wird der eigentliche Interruptvektor ausgeführt; steht dort ein RJMP oder JMP, kommen nochmal zwei bzw drei Takte dazu. Dir fehlen eher zwei bis drei Takte Reaktionszeit bei einem IRQ, als ein paar Words im Gesamt-Flash... naja, beim Tiny4/9 oder so vielleicht...
Es kann also durchaus sinnig sein, die Interrupt-Service-Routinen in der Nähe der IVT anzulegen, und sie statt mit JMP mit RJMP anzuspringen.
(Gilt ja eh erst für Controller mit viel Flash. Trotzdem kann man das dann noch auf die Spitze treiben - die IVT ist ja dann zwei Words "breit" (damit JMP reinpaßt), RJMP belegt aber nur ein Word. Man kann also jedesmal vor dem RJMP einen anderen single-Word-Mnemonic platzieren (wobei die einzigen Doppelwort-Instructions ja eh CALL, JMP, LDS und STS sind)
C (also das Studio) läßt aus der IVT "irgendwohin" rausspringen. Meiner Meinung nach hinter den Code der Main(). Vermutlich werden dort ggfs. auch sämtliche verwendete ISRs platziert (hatte ich damals nicht mit drin), nicht verwendete landen auf einer gemeinsamen Adresse, von der ein Sprung zum Reset-Vektor erfolgt.
Hat gegenüber einfachen RETIs den Vorteil, daß man einen unbeabsichtigt scharfgemachten (=Programmfehler) auch erkennt.
Verwendest Du normalen Code in der IVT, erkennst Du diesen Fehler natürlich auch - wann Du ihn findest, ist 'ne andere Frage.
Kann ich auch Funktionen bauen?
Klar, hab doch oben bereits alle Operationen genannt. Mit den vier CALLs kannst Du die Adresse einer Subroutine anspringen, mit RET zurückkehren.
Um die Übergabe irgendwelcher Parameter oder Ergebnisse mußt Du Dich selbst kümmern.
Aber meist willst Du Dich doch mit derlei Overhead gar nicht rumschlagen - das hier ist Assembler, der AVR hat zweiunddreißig Rechenregister. Mußt Du wirklich alles ständig zwischen SRAM und Rechenregistern hin und herschaufeln?