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

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

リンクミス

ld -m i386pe -n -Ttext 0xC200 -static -o third.exe --start-group OSStart.o GDT.o IO.obj --end-group

cygwinでリンクしたときに以下のエラーが発生。

GDT.c:11: undefined reference to `lgdt'

以下のnasmのファイル(IO.asm→IO.obj)とGDT.hとGDT.cがある。原因を探ってるところ。lgdtの名前が悪いのではないかと試しにasm_lgdtに変えてみたが変化は無かった。何かを見落としている

GLOBAL lgdt, _lgdt

lgdt:
_lgdt:
    MOV  AX, [ESP + 4]
    MOV  [ESP + 6], AX
    LGDT [ESP + 6]
    RET
#ifndef _GDT_H_
#define _GDT_H_

#include "type.h"

typedef struct{
    uintptr_t addr;
    uint_16t limit;
} GDTR;

typedef struct{
    uint_16t limit_low;
    uint_16t base_low;
    uint_8t base_mid;
    uint_8t access_right;
    uint_8t limit_high;
    uint_8t base_high;
} SegmentDescriptor;

void initGDTR(GDTR* gdtr, uintptr_t addr, uint_16t count);
void loadGDT(GDTR* gdtr);
void setGDT(GDTR* gdtr, uint_32t index, uintptr_t addr, uint_32t limit, uint_32t access_right);

extern void lgdt(int limit, int addr);
#endif
#include "include/GDT.h"

void initGDTR(GDTR* gdtr, uintptr_t addr, uint_16t count){
    gdtr->addr = addr;
    gdtr->limit = count * sizeof(SegmentDescriptor) - 1;
    
    setGDT(gdtr, 0, 0, 0, 0);
}

void loadGDT(GDTR* gdtr){
    lgdt(gdtr->addr, gdtr->limit);
}

void setGDT(GDTR* gdtr, uint_32t index, uintptr_t addr, uint_32t limit, uint_32t access_right){
    SegmentDescriptor* sd = (SegmentDescriptor*)(gdtr->addr) + index;

    if(limit > 0xfffff){
        access_right |= 0x8000;
        limit /= 0x1000;
    }

    sd->limit_low = limit & 0xffff;
    sd->base_low  = addr  & 0xffff;
    sd->base_mid  = (addr >> 16) & 0xff;
    sd->access_right = access_right & 0xff;
    sd->limit_high = ((limit >> 16) & 0x0f) | ((access_right >> 8) & 0xf0);
    sd->base_high  = (addr >> 24) & 0xff;
}