c - nasm macro doesn't work properly -


i'm trying set idt of kernel i'm getting linking error:

 bin/obj/idt.o: in function `setup_idt':  idt.c:(.text+0x9b): undefined reference `interrupt_handler_1' 

the error says interrupt_handler_1 isn't defined macro in interrupt_manager.asm:

%macro no_error_code_interrupt_handler 1 global interrupt_handler_%1 interrupt_handler_%1:    cli    push    dword 0                     ; push 0 error code    push    dword %1                    ; push interrupt number    jmp     common_interrupt_handler    ; jump common handler %endmacro 

here setyup_idt function:

extern void interrupt_handler_1();  void setup_idt() {     // set special idt_pointer     idt_pointer.limit = ( sizeof(struct interruptdescriptortableentry) * 256 ) - 1; // subsract 1 because sizeof doesn't start 0     idt_pointer.address = (uint32)&idt;      // clear whole idt zeros     memset(&idt, 0, sizeof(struct interruptdescriptortableentry) * 256 );      for(unsigned int = 0; < 256; i++)     {         idt_set_gate(i, (uint32)&interrupt_handler_1, 0x8, 0x8e);        }      __asm__ __volatile__("lidt %0": :"m"(idt_pointer));  } 

what did made wrong?

extra question: there macro/another way link automatically entry of gdt interrupt handler, let me try explain myself better:

what want this:

    for(unsigned int = 0; < 256; i++)     {         idt_set_gate(i, (uint32)&interrupt_handler_[i], 0x8, 0x8e);        } 

where interrupt_handler[i] interrupt handler_[i] replaced nasm macro

you need expand macro in nasm code. macro definition doesn't generate code. needs explicitly used in nasm code.

you can use %rep directive repeatedly expand macro different parameters. this:

    extern common_interrupt_handler  %macro error_code_interrupt_handler 1 global interrupt_handler_%1 interrupt_handler_%1:    push    dword %1                    ; push interrupt number    jmp     common_interrupt_handler    ; jump common handler %endmacro  %macro no_error_code_interrupt_handler 1 global interrupt_handler_%1 interrupt_handler_%1:    push    dword 0                     ; push 0 error code    push    dword %1                    ; push interrupt number    jmp     common_interrupt_handler    ; jump common handler %endmacro  ; cpu exceptions have error codes, don't  %assign intnum 0 %rep 8 - intnum     no_error_code_interrupt_handler intnum     %assign intnum intnum + 1 %endrep  error_code_interrupt_handler 8 no_error_code_interrupt_handler 9  %assign intnum 10 %rep 16 - intnum     error_code_interrupt_handler intnum     %assign intnum intnum + 1 %endrep  no_error_code_interrupt_handler 16 error_code_interrupt_handler 17 no_error_code_interrupt_handler 18 no_error_code_interrupt_handler 19 no_error_code_interrupt_handler 20  %assign intnum 21   ; first (currently) unassigned cpu exception %rep 32 - intnum     no_error_code_interrupt_handler intnum     %assign intnum intnum + 1 %endrep  %assign intnum 32   ; first user defined interrupt %rep 256 - intnum     no_error_code_interrupt_handler intnum     %assign intnum intnum + 1 %endrep  ; define table of interrupt handlers c code use      global interrupt_handler_table interrupt_handler_table:  %assign intnum 0 %rep 256     dd  interrupt_handler_ %+ intnum     %assign intnum intnum + 1 %endrep 

the code above creates table of interrupt handlers can use in c code this:

extern uint32 interrupt_handler_table[256];  for(unsigned int = 0; < 256; i++) {     idt_set_gate(i, interrupt_handler_table[i], 0x8, 0x8e);    } 

note i've created error_code_interrupt_handler macro cpu exceptions generate error codes. also, i've removed unnecessary cli instruction code. since you're using interrupt gates in idt, interrupt enable flag automatically cleared.


Comments