Your question isn't really specific enough to give a good answer to. Are you talking about an interrupt handler in general or one for a specific operating system? Also, it's very architecture dependent. Certain processors generate many levels of interrupt (which have a priority) others only have a single interrupt level. Then there's NMI interrupts, which are usually always generated by hardware.
Also, what level do you need to know how an interrupt happens? I hope this isn't patronising... but I think of an interrupt in terms of a guy writing a letter. The telephone rings and he stops writing the letter, answers the phone and upon completing the call, returns to writing the letter exactly where he left off. (The call being the interrupt and the handling of the interrupt being him answering the call).
Let's take a simple example of an interrupt, say one generated by a timer. For ease, I'm going to refer to an Amiga interrupt because they're very raw in nature whereas in certain architectures, there's some operating system intervention before your application gets to handle the interrupt.
First thing is to understand the hardware. In order for you to get the interrupt from the timer, you'd have to enable it. Usually there's a hardware register for doing this. This register will mask what interrupts are enabled and what interrupts aren't. Now, if you've enabled this interrupt, when it occurs, the processor will stop what it is doing, perform a stack swap (to a supervisor stack) and call a interrupt handling routine or vector at a specific address. For you to handle this interrupt yourself, you'd need to write a handler and write its address into the handler address or vector. Then your routine would be called.
Your routine needs to be aware of the fact that there might be a time constraint on how long you have to process the interrupt, also that you may be interrupted by a higher priority interrupt and that you must service the interrupt or pass the interrupt along to the previous handler who was there before you.
In your interrupt handling routine you should... check for where the interrupt came from because there may be many sources and then you can decide if you want to handle the interrupt. You might have to interrogate hardware devices to identify the source of the interrupt. If it is one you want to handle, then upon performing whatever you want to do, you must acknowledge the interrupt and tell the hardware that you have serviced the interrupt. Usually there will be a specific register for doing this. Then you can exit your interrupt handler, but ONLY if you've handled the interrupt.
When you exit your interrupt handler, with an instruction like rte or rti, the stacks will then again be swapped back from the supervisor stack to the user stack.
You need to be aware that certain architectures build certain stack-frames and they nearly all differ from each other. Usually however, you will always find the Status register and Program Counter on the stack, but you may and probably will find MUCH more on the stack (the supervisor stack)
The program counter will be the return address that will be jumped to upon exit from your handler.