2017-04-23 1 views
1

GCC을 사용하여 간단한 운영 체제를 작성하려고하는데, 입력 한 디스플레이에 텍스트를 표시 할 수 있습니다. 나는 C에 인터럽트 테이블을 가지고 있는데 외부 어셈블리 언어 모듈보다는 인라인 어셈블리를 사용하여로드 할 수 있기를 원합니다.인라인 어셈블리에서 LIDT를 사용하여 인터럽트 벡터 테이블을로드하는 방법은 무엇입니까?

내가 찾고있는 것은 C 인라인 어셈블리에 포인터를 전달하는 방법입니다.

메모리 피연산자 LIDT 인 요구 I 인라인를 시도하고 다음 명령어 글로벌 디스크립터 테이블 레지스터 (GDTR) 또는 인터럽트 디스크립터 테이블 레지스터에

로드 소스 피연산자의 값 (IDTR) . 소스 피연산자는 글로벌 설명자 테이블 (GDT) 또는 인터럽트 설명자 테이블 (IDT)의 기본 주소 (선형 주소)와 제한 (테이블의 크기)을 포함하는 6 바이트 메모리 위치를 지정합니다. 피연산자 크기 속성이 32 비트이면 16 비트 제한 (6 바이트 데이터 피연산자의 하위 2 바이트) 및 32 비트 기본 주소 (데이터 피연산자의 상위 4 바이트)가 레지스터에로드됩니다. operand-size 속성이 16 비트이면 16 비트 제한 (하위 2 바이트)과 24 비트 기본 주소 (세 번째, 네 번째 및 다섯 번째 바이트)가로드됩니다. 여기서 피연산자의 상위 바이트는 사용되지 않으며 GDTR 또는 IDTR의 기본 주소의 상위 바이트는 0으로 채워집니다.

+1

이것은 보호 모드에 있다고 가정하고 'lidt' 명령을 사용하여 6 바이트 IDT 레코드 (기본 주소와 제한이 있음)가있는 메모리 위치에서 IDTR을로드하려고합니다. –

답변

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에서 그것을 할 수 있기를 원했습니다. –

관련 문제