Here is my code:
- interruptstubs.s:
.set IRQ_BASE, 0x20
.section .text
.extern _ZN16InterruptManager15handleInterruptEhj
.global _ZN16InterruptManager22IgnoreInterruptRequestEv
.macro HandleException num
.global _ZN16InterruptManager16HandleInterruptException\num\()Ev
_ZN16InterruptManager16HandleInterruptException\num\()Ev:
movb $\num, (interruptnumber)
jmp int_bottom
.endm
.macro HandleInterruptRequest num
.global _ZN16InterruptManager26HandleInterruptRequest\num\()Ev
_ZN16InterruptManager26HandleInterruptRequest\num\()Ev:
movb $\num+IRQ_BASE, (interruptnumber)
jmp int_bottom
.endm
HandleInterruptRequest 0x00
HandleInterruptRequest 0x01
int_bottom:
pusha
pushl %ds
pushl %es
pushl %fs
pushl %gs
pushl %esp
push (interruptnumber)
call _ZN16InterruptManager15handleInterruptEhj
movl %eax, %esp
popl %gs
popl %fs
popl %es
popl %ds
popa
_ZN16InterruptManager22IgnoreInterruptRequestEv:
iret
.data
interruptnumber: .byte 0
- interrupts.h:
class InterruptManager
{
public:
static uint32_t handleInterrupt(uint8_t interruptNumber, uint32_t esp);
};
- interrupts.cpp:
#include "interrupts.h"
uint32_t InterruptManager::handleInterrupt(uint8_t interruptNumber, uint32_t esp)
{
printf((char *)" INTERRUPT");
return esp;
}
I compile/assemble/link with these commands:
as --32 -o loader.o loader.s
g++ -m32 -Iinclude -fno-use-cxa-atexit -fleading-underscore -fno-exceptions -fno-builtin -nostdlib -fno-rtti -fno-pie -o gdt.o -c gdt.cpp
g++ -m32 -Iinclude -fno-use-cxa-atexit -fleading-underscore -fno-exceptions -fno-builtin -nostdlib -fno-rtti -fno-pie -o port.o -c port.cpp
g++ -m32 -Iinclude -fno-use-cxa-atexit -fleading-underscore -fno-exceptions -fno-builtin -nostdlib -fno-rtti -fno-pie -o interrupts.o -c interrupts.cpp
as --32 -o interruptstubs.o interruptstubs.s
g++ -m32 -Iinclude -fno-use-cxa-atexit -fleading-underscore -fno-exceptions -fno-builtin -nostdlib -fno-rtti -fno-pie -o kernel.o -c kernel.cpp
ld -melf_i386 -no-pie -T linker.ld -o mykernel.bin loader.o gdt.o port.o interrupts.o interruptstubs.o kernel.o
the whole code structure is like this above. uint32_t is defined before and here I didn't show it because I don't think it caused problem.
Now when calling the method 'handleInterrupt()' from the .cpp file in my asm code, it has compile error:
ld: interruptstubs.o: in function `int_bottom':
(.text+0xf): undefined reference to `InterruptManager::handleInterrupt(unsigned char, unsigned int)'
I wonder why it didn't work when linking because I have declared .extern _ZN16InterruptManager15handleInterruptEhj in front of the file.
I have searched almost everything on the Internet and didn't get the answer.
-fleading-underscore? You are telling G++ to use a leading underscore which in the case of the classes ends up using a double underscore__on member names. You'd have to modify your assembly code in interruptstubs.s to use__instead of_which is the cause of the problem. I'd recommend not using-fleading-underscorebut there might be a reason you are?