mod idt;

macro_rules! handler {
    ($name: ident) => {{
        #[naked]
        extern "C" fn wrapper() -> ! {
            unsafe {
                asm!("mov rdi, rsp
                      sub rsp, 8 // align the stack pointer
                      call $0"
                      :: "i"($name as extern "C" fn(
                          *const ExceptionStackFrame) -> !)
                      : "rdi" : "intel");
                ::core::intrinsics::unreachable();
            }
        }
        wrapper
    }}
}

lazy_static! {
    static ref IDT: idt::Idt = {
        let mut idt = idt::Idt::new();

        idt.set_handler(0, handler!(divide_by_zero_handler));

        idt
    };
}

pub fn init() {
    IDT.load();
}

#[derive(Debug)]
#[repr(C)]
struct ExceptionStackFrame {
    instruction_pointer: u64,
    code_segment: u64,
    cpu_flags: u64,
    stack_pointer: u64,
    stack_segment: u64,
}

use vga_buffer::print_error;

extern "C" fn divide_by_zero_handler(stack_frame: *const ExceptionStackFrame)
    -> !
{
    unsafe {
        print_error(format_args!("EXCEPTION: DIVIDE BY ZERO\n{:#?}",
            *stack_frame));
    }
    loop {}
}

mod idt;

lazy_static! {
    static ref IDT: idt::Idt = {
        let mut idt = idt::Idt::new();

        idt.set_handler(0, divide_by_zero_wrapper);

        idt
    };
}

pub fn init() {
    IDT.load();
}

#[derive(Debug)]
#[repr(C)]
struct ExceptionStackFrame {
    instruction_pointer: u64,
    code_segment: u64,
    cpu_flags: u64,
    stack_pointer: u64,
    stack_segment: u64,
}

use vga_buffer::print_error;

#[naked]
extern "C" fn divide_by_zero_wrapper() -> ! {
    unsafe {
        asm!("mov rdi, rsp
              sub rsp, 8 // align the stack pointer
              call $0"
              :: "i"(divide_by_zero_handler as extern "C" fn(_) -> !)
              : "rdi" : "intel");
        ::core::intrinsics::unreachable();
    }
}

extern "C" fn divide_by_zero_handler(stack_frame: *const ExceptionStackFrame)
    -> !
{
    unsafe {
        print_error(format_args!("EXCEPTION: DIVIDE BY ZERO\n{:#?}",
            *stack_frame));
    }
    loop {}
}

--- 
+++ 
@@ -1,10 +1,28 @@
 mod idt;
+
+macro_rules! handler {
+    ($name: ident) => {{
+        #[naked]
+        extern "C" fn wrapper() -> ! {
+            unsafe {
+                asm!("mov rdi, rsp
+                      sub rsp, 8 // align the stack pointer
+                      call $0"
+                      :: "i"($name as extern "C" fn(
+                          *const ExceptionStackFrame) -> !)
+                      : "rdi" : "intel");
+                ::core::intrinsics::unreachable();
+            }
+        }
+        wrapper
+    }}
+}
 
 lazy_static! {
     static ref IDT: idt::Idt = {
         let mut idt = idt::Idt::new();
 
-        idt.set_handler(0, divide_by_zero_wrapper);
+        idt.set_handler(0, handler!(divide_by_zero_handler));
 
         idt
     };
@@ -26,18 +44,6 @@
 
 use vga_buffer::print_error;
 
-#[naked]
-extern "C" fn divide_by_zero_wrapper() -> ! {
-    unsafe {
-        asm!("mov rdi, rsp
-              sub rsp, 8 // align the stack pointer
-              call $0"
-              :: "i"(divide_by_zero_handler as extern "C" fn(_) -> !)
-              : "rdi" : "intel");
-        ::core::intrinsics::unreachable();
-    }
-}
-
 extern "C" fn divide_by_zero_handler(stack_frame: *const ExceptionStackFrame)
     -> !
 {
Add a handler macro that creates wrapper functions
