2017-04-23 14 views
1

GCCを使用して簡単なオペレーティングシステムを作成しようとしています。これにより、入力したディスプレイにテキストを表示できます。私はロードする必要があり、外部アセンブリ言語モジュールではなくインラインアセンブリを使用してできるようにするために、割り込みテーブルCを持っています。インラインアセンブリからLIDTを使用して割り込みベクタテーブルをロードする方法は?

私が探しているのは、Cポインタをインラインアセンブリに渡す方法です。

メモリオペランドを必要と私はインラインしようとしていた命令がLIDT次のとおりです。

は、グローバル記述子テーブルレジスタ(GDTR)または割り込みディスクリプタ・テーブル・レジスタ(IDTR)にソースオペランドの値をロードします。ソース・オペランドは、グローバル・ディスクリプタ・テーブル(GDT)または割り込みディスクリプタ・テーブル(IDT)のベース・アドレス(リニア・アドレス)とリミット(バイト・テーブルのサイズ)を含む6バイトのメモリ位置を指定します。オペランドサイズ属性が32ビットの場合、16ビットの制限(6バイトのデータオペランドの下位2バイト)と32ビットのベースアドレス(データオペランドの上位4バイト)がレジスタにロードされます。 operand-size属性が16ビットの場合、16ビットの制限(下位2バイト)と24ビットのベースアドレス(3番目、4番目、5番目のバイト)がロードされます。ここでは、オペランドの上位バイトは使用されず、GDTRまたはIDTRのベースアドレスの上位バイトは0で埋められます。

+1

これは保護されたモードで、6バイトのIDTレコード(ベースアドレスと制限を持っています)を含むメモリ位置からIDTRを読み込むために 'lidt'命令を使用するとしますか? –

答えて

1

あなたは、任意のコードを提供していない、とあなたはCコンパイラを言うことはありませんが、私はGCCと32ビットのカーネルを仮定します。これは、あなたが何ができるかの例です:

#include <stdint.h> 

struct idt_record 
{ 
    uint16_t limit;  /* Size of IDT array - 1 */ 
    uintptr_t base;  /* Pointer to IDT array */ 
} __attribute__((packed)); 

void load_idt (struct idt_record *idt_r) 
{ 
    __asm__ ("lidt %0" :: "m"(*idt_r)); 
} 

このコードはインラインアセンブリを使用していますし、それがLIDT命令で使用される拡張インラインテンプレートにIDTレコードのアドレスを渡します。 mconstraintを使用します。制約へのパラメータが(idt_r)であれば、ポインタへのメモリ参照が渡されます。私たちは*で逆参照するように実際のデータへのメモリ参照が必要なので、私は"m"(*idt_r)を使用しています。あなたが私達にあなたのデータ構造を示していた場合、私は、このような提供する必要はない

はあなたの実際のIDT配列を指すようにbaseを設定する必要がとlimitIDT配列マイナス1の大きさになります一般的な応答。 IDTレコード構造をどのように定義したか分かりませんので、この例では素早く単純なレコード構造を使用しました。

おそらく、load_idt関数をインクルードファイル内に提供し、その関数をstatic inlineとマークします。


:あなたはIDTレコードの構造を使用している場合を確認してくださいあなたパック私は__attribute__((packed))でやっていることと同様の構造。パックしないと、limitbaseの間に追加の2バイトが追加され、壊れたIDTレコードが生成されます。

+1

ありがとう!これは私の問題を解決しました。私はオンラインでそれを行う方法について多くを見つけましたが、私は本当にgccからやりたいと思っていました。 –

関連する問題