How can I switch on/off the keyboard LEDs?
You could use something like:
%define LEDSCROLL 1
%define LEDNUMLOCK 2
%define LEDCAPS 4
;Set keyboard LED's
; al LED's
mov cl,0xed ;Set status indicators
call readFromDataPort ;Wait until input buffer empty
Now I'm asking, is there in some register or something like that saved which exception/interrupt has occured? It would be faster to program my exception handler then.
For exceptions and software interrupts there isn't (for IRQ's there is, sort of).
To determine if an IRQ was the cause you can check the ISR (In Service Register) of both PIC chips (or the local APIC if you're using that instead). This doesn't always work as expected - it'll tell you which IRQs have been sent to the CPU but not which IRQs the CPU has sent to software (different CPUs "cache" some IRQs if interrupts are disabled).
To determine if it was a software interrupt you could look at the saved CS:EIP to see if either INTO, INT3 or INT N was the instruction that was executed before the interrupt. You'd need to be careful though - for e.g. if someone has a bug like "jmp <nowhere_in_particular>" that causes a page fault, and your exception handler tries to see what was running you'd also cause a page fault, which would cause a double fault (and probably a triple fault). To avoid this you'd need to check if the page was present and can be accessed first.
You'd also need to check if an IRQ was the cause first, otherwise you could get an IRQ immediately after a software interrupt and you'd think the software interrupt happened twice.
The information above is for general knowledge - I definately wouldn't suggest actually doing something like this.
Generally you'd determine which exception/interrupt occured by setting a different address for each one in the IDT. For IDT entries used by IRQs and exception handlers, set the protection flags so user level code can't generate them with a software interrupt (an attempt would result in a general protection fault). That way you can do something like:
handler: ;eax = interrupt number on entry
That would be the fastest, simplest, most stable method...