2016-09-23 9 views
2

ヘルプ、私はOSを実行し、クラッシュします! IDT Loadetは正常です。私が間違っていたことは?本当に難しい!私は保護モードでOSを書く必要があります!アセンブラ+ CまたはI割り込みが動作しない

#define IT 0x000000 
    #define IR 0x000800 
    #define SCS 0x8 
    #define IRQ_HANDLER(func) void func (void)\ 
    {asm(#func ": pusha \n call _" #func " \n movb $0x20, %al \n outb %al, $0x20 \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"); 
    } 
    ... 


私が何をすべきかを知りません!

+2

このようなインラインアセンブリは使用できません。コンパイラはスタックを 'popf'を実行するときに' pushf \ ncli'の後と同じ状態に保つことを約束しません。 –

+2

答えとコメントの上にすでに。私はあなたが 'opb(0x21,0xfd); opb(0xa1,0xff); 'これはキーボード割り込みである** IRQ1を除く**すべての16個の割り込みをマスクすることを示唆していますが、次にIRQ0であるタイマの割り込みハンドラを設定します。あなたはそれをするつもりでしたか? 0xfd =バイナリ11111101これはマスタPICをIRQ1に設定したものです。たぶんあなたは0xfeを意味するのでしょうか? –

答えて

3

まず、ほとんどのコンパイラでは、create an ISR directlyを使用できます。

第2に、最初に処理されなかったまたは偽の割り込み(最初は見えているようなことです)でシステムをクラッシュさせない限り、最初からすべてをキャッチする必要があります。

適切な割り込み処理サブシステムを使用すると、コードがはるかにクリーンでポータブルになり、ダムバス(ISAなど)のIRQを調べ、共有IRQをきれいにルーティングすることができます。

ほとんどのエミュレータはGDBプロトコルをサポートしており、この種のフォールトを容易にデバッグできます。たとえば、-d int-no-rebootでQEMUを起動して、このような問題をデバッグすることができます。障害が発生すると、デバッガからその問題を検査できます。 QEMU Wikibookで始めるためのいくつかの指示があります。 BOCHSを試してみるといいかもしれませんし、低レベルのものより優れている内部デバッガが付属していて、時にはエミュレーションがより正確です。

+0

ほとんどの32ビットx86コンパイラでは、プロテクトモードの割り込み処理は、汎用的な割り込み関数のプロローグとエピローグで処理するには複雑すぎるため、ISRを直接作成することはできません。 –

+0

GCCとClangは、BorlandとWatcom IIRCと同様に(何年も前から...)。 –

+0

うーん... GCCは使用されていませんでしたが、1年前に追加したようです。 Borlandの32ビットCコンパイラは、それをサポートしていません。 Watcomのように見える。いずれにしても、保存されたレジスタにアクセスすることはできず、割り込みリターン時には内容を切り替えることができないため、オペレーティングシステムではあまり役に立ちません。 –

関連する問題