マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

一般保護例外

qemuでエラー発生。それは一般保護例外だった。原因はfar callにあるっぽい。下のソースのg_GDTManager->setGDTの引数は、インデックス、ベース、リミット、アクセス権の順となっている。g_GDTManager->loadGDTR()はLGDTを呼び出しているだけ。IO::farCallの引数はCSレジスタの値、EIPの値の順。

    g_GDTManager->setGDT(1, 0, 0xffffffff, 0x409a);
    //2〜5は省略
    g_GDTManager->loadGDTR();
    //いろんな処理省略
    g_GDTManager->setGDT(6, 0, 0xffffffff, 0x4092);
    IO::farCall(6 * 8, entry->getMainAddress());

このIO::farCallで駄目っぽい。それで、試しに

    IO::farCall(1 * 8, entry->getMainAddress());

とやってみるとうまくいく。次にg_GDTManager->loadGDTR()をもう一度呼び出してみたが駄目だった

    g_GDTManager->setGDT(6, 0, 0xffffffff, 0x4092);

    g_GDTManager->loadGDTR();

    IO::farCall(6 * 8, entry->getMainAddress());

1と6に何の差があるんだ?
6のアクセス権が間違っていた。アクセス権を変えたらうまくいった。なんてことだ…