Rewrote low level exception handling and registers restoring code

A few changes here:
 - Added a registers structure that can be passed around in the
   kernel in an architecture independent way. It's just a
   struct after all.
 - Restore registers now takes a pointer to a registers struct
   and restores the registers from that.
 - Exception handling changed in a few ways:
    * Exception handlers build the register struct and pass it
      (along with the error code and vector) to the C handler.
    * C exception handlers are called via a jump table (exn_table)
    * Returning from the assembly exception handlers uses
      restore_registers().
Initial spinlock implementation