x86: irq: Cut out the work done by Michel Megens.

The setting up of IRQ's was flawed. His implementation, prepared a stub
function, for which memory was allocated.

With the allocated memory, the IRQ stub code was then copied into the
allocated region, before a few pointers were set.

In future implementations, a stub will be made present, which then calls
a function pointer implemented in this stub. This can either be fetched
from a separate table, easier to implement in C, or point to a generic
function, that contains an IRQ identifying number.

This static approach might require a little more memory in systems that
don't require the entire IRQ space to be available, but it does help in
keeping the code more debuggable and understandable.

Also, maintaining a static approach, allows us to keep track of where
the code is in the future, so that we can detect whenever the EIP goes
somewhere it shouldn't (in case of a stack or heap overflow attack).

Note that in the case of detecting a stack overflow attack, the stack
should be registered in a different location to enable it to be marked
as unexecutable by the page tables.

Signed-off-by: Bart Kuivenhoven <bemkuivenhoven@gmail.com>