Assembler + C 否则我无法让中断工作
Assembler + C or I Can't Get Interrupts Working
求助,我 运行 OS 它崩溃了! IDT Loadet 正常。我做错了什么?真的很难!我需要在保护模式下写os!
#define IT 0x000000
#define IR 0x000800
#define SCS 0x8
#define IRQ_HANDLER(func) void func (void)\
{asm(#func ": pusha \n call _" #func " \n movb [=10=]x20, %al \n outb %al, [=10=]x20 \n popa \n iret \n");}\
void _ ## func(void)
void init_interrupts() {
int i=0;
unsigned short *ir=IR;
for(i=0;i<256*8;i++){
*(ir+i)=0;
}
*(ir)=256*8-1;
*(ir+2)=(IT &0xFFFF0000)>>16;
*(ir+4)=(IT&0x0000FFFF);
set_int_handler(0x20, timer_int_handler, 0x8E);
//set_int_handler(0x21, print_c, 0x8E);
asm("lidt 0(,%0,)"::"a"(IR));
opb(0x21,0xfd);
opb(0xa1,0xff);
opb(0x20,0x20); opb(0xa0,0x20);
asm("sti");
}
void set_int_handler(char index, void *handler, char type) {
asm("pushf \n cli");
char *ad=IT;
*(ad+index*8)=(char)(handler)&0x000000FF;
*(ad+index*8+1)=((char)(handler)&0x0000FF00)>>8;
*(ad+index*8+2)=0x8;
*(ad+index*8+3)=0;
*(ad+index*8+4)=0;
*(ad+index*8+5)=type;
*(ad+index*8+6)=((char)(handler)&0x00FF0000)>>16;
*(ad+index*8+7)=((char)(handler)&0xFF000000)>>24;
asm("popf");
}
...
我不知道该怎么办!
首先,大多数编译器都允许您以某种方式 create an ISR directly。
其次,您应该从一开始就捕获所有内容,除非您希望系统在第一个未处理或虚假中断时崩溃(乍一看似乎正在发生)。
适当的中断处理子系统将使代码更加简洁和可移植,允许您探测哑总线(如 ISA)的 IRQ 并干净地路由共享 IRQ。
大部分仿真器都支持GDB协议,让您轻松调试此类故障。例如,您可以使用 -d int
和 -no-reboot
启动 QEMU 来调试此类问题,一旦发生故障,您可以从调试器中检查它。您可以在 QEMU Wikibook 中找到一些入门说明。您可能还想尝试 BOCHS,它带有一个内部调试器,在低级别的东西上更好,而且仿真有时更准确。
求助,我 运行 OS 它崩溃了! IDT Loadet 正常。我做错了什么?真的很难!我需要在保护模式下写os!
#define IT 0x000000
#define IR 0x000800
#define SCS 0x8
#define IRQ_HANDLER(func) void func (void)\
{asm(#func ": pusha \n call _" #func " \n movb [=10=]x20, %al \n outb %al, [=10=]x20 \n popa \n iret \n");}\
void _ ## func(void)
void init_interrupts() {
int i=0;
unsigned short *ir=IR;
for(i=0;i<256*8;i++){
*(ir+i)=0;
}
*(ir)=256*8-1;
*(ir+2)=(IT &0xFFFF0000)>>16;
*(ir+4)=(IT&0x0000FFFF);
set_int_handler(0x20, timer_int_handler, 0x8E);
//set_int_handler(0x21, print_c, 0x8E);
asm("lidt 0(,%0,)"::"a"(IR));
opb(0x21,0xfd);
opb(0xa1,0xff);
opb(0x20,0x20); opb(0xa0,0x20);
asm("sti");
}
void set_int_handler(char index, void *handler, char type) {
asm("pushf \n cli");
char *ad=IT;
*(ad+index*8)=(char)(handler)&0x000000FF;
*(ad+index*8+1)=((char)(handler)&0x0000FF00)>>8;
*(ad+index*8+2)=0x8;
*(ad+index*8+3)=0;
*(ad+index*8+4)=0;
*(ad+index*8+5)=type;
*(ad+index*8+6)=((char)(handler)&0x00FF0000)>>16;
*(ad+index*8+7)=((char)(handler)&0xFF000000)>>24;
asm("popf");
}
...
我不知道该怎么办!
首先,大多数编译器都允许您以某种方式 create an ISR directly。
其次,您应该从一开始就捕获所有内容,除非您希望系统在第一个未处理或虚假中断时崩溃(乍一看似乎正在发生)。
适当的中断处理子系统将使代码更加简洁和可移植,允许您探测哑总线(如 ISA)的 IRQ 并干净地路由共享 IRQ。
大部分仿真器都支持GDB协议,让您轻松调试此类故障。例如,您可以使用 -d int
和 -no-reboot
启动 QEMU 来调试此类问题,一旦发生故障,您可以从调试器中检查它。您可以在 QEMU Wikibook 中找到一些入门说明。您可能还想尝试 BOCHS,它带有一个内部调试器,在低级别的东西上更好,而且仿真有时更准确。