我正在尝试设置内核的IDT,但出现以下链接错误:

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

错误说明未定义中断处理程序1,但它是中断管理器中的宏。asm:
%macro no_error_code_interrupt_handler 1
global interrupt_handler_%1
interrupt_handler_%1:
   cli
   push    dword 0                     ; push 0 as error code
   push    dword %1                    ; push the interrupt number
   jmp     common_interrupt_handler    ; jump to the common handler
%endmacro

下面是setyup\u idt函数:
extern void interrupt_handler_1();

void setup_idt()
{
    // Set the special idt_pointer
    idt_pointer.limit = ( sizeof(struct InterruptDescriptorTableEntry) * 256 ) - 1; // Subsract 1 because sizeof doesn't start from 0
    idt_pointer.address = (uint32)&idt;

    // Clear the whole idt to zeros
    memset(&idt, 0, sizeof(struct InterruptDescriptorTableEntry) * 256 );

    for(unsigned int i = 0; i < 256; i++)
    {
        idt_set_gate(i, (uint32)&interrupt_handler_1, 0x8, 0x8E);
    }

    __asm__ __volatile__("lidt %0": :"m"(idt_pointer));

}

我做错什么了?
额外问题:是否有一个宏/另一种方法可以将GDT的i项自动链接到i中断处理程序,让我试着更好地解释自己:
我想做的是这样的事情:
    for(unsigned int i = 0; i < 256; i++)
    {
        idt_set_gate(i, (uint32)&interrupt_handler_[i], 0x8, 0x8E);
    }

如果中断处理程序[i]是中断处理程序,则中断处理程序将被nasm宏替换

最佳答案

您需要在NASM代码中展开宏。宏定义本身不会生成任何代码。它需要在NASM代码中显式地使用。
可以使用%rep指令使用不同的参数重复展开宏。像这样的:

    extern common_interrupt_handler

%macro error_code_interrupt_handler 1
global interrupt_handler_%1
interrupt_handler_%1:
   push    dword %1                    ; push the interrupt number
   jmp     common_interrupt_handler    ; jump to the common handler
%endmacro

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

; Some CPU exceptions have error codes, some 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 a table of interrupt handlers for C code to use

    global interrupt_handler_table
interrupt_handler_table:

%assign intnum 0
%rep 256
    dd  interrupt_handler_ %+ intnum
    %assign intnum intnum + 1
%endrep

上面的代码创建了一个包含所有中断处理程序的表,您可以在C代码中使用这些处理程序,如下所示:
extern uint32 interrupt_handler_table[256];

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

注意,我已经为那些生成错误代码的CPU异常创建了一个error_code_interrupt_handler宏。另外,我已经从代码中删除了不必要的CLI指令。由于您在IDT中使用中断门,中断启用标志将被自动清除。

关于c - nasm宏无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38834670/

10-12 00:52