2012-01-17 2 views
2

이 어셈블리 코드를 인라인 어셈블리로 작성하는 방법은 무엇입니까? 컴파일러 : gcc (i586-elf-gcc). GAS 구문이 나를 혼란스럽게합니다. gcc에서 작동하는 인라인 어셈블리로 이것을 작성하는 방법을 알려주십시오.인텔 스타일 어셈블리 코드를 GCC 인라인 어셈블리로 다시 작성하십시오.

.set_video_mode: 
    mov ah,00h 
    mov al,13h 
    int 10h 

.init_mouse: 
    mov ax,0 
    int 33h 

비슷한 조립품입니다. 어셈블리 루틴을 C 프로그램에서 호출하기 위해 별도로 작성했습니다. 나는 이것들과 C 자체로부터 좀 더 많은 인터럽트를 호출 할 필요가있다.

또한 호출 할 인터럽트 루틴에 따라 일부 레지스터에 값을 입력해야합니다. 어떻게하는지 말해줘.

내가 원하는 것은 C에서 인터럽트 루틴을 호출하는 것입니다. int86()을 사용하여이 작업을 수행 할 수도 있지만 그 함수의 소스 코드가 없습니다. 내가 C에서 인터럽트를 호출 할 수 있도록 int86()이 필요합니다.

인터럽트를 호출하거나 직접적인 하드웨어 액세스를 위해 아무런 제약이 없도록 내 자신의 작은 OS를 개발 중입니다.

+0

erm ...BIOS 인터럽트 (예 : MSDOS)에 대한 직접 액세스 권한을 부여하는 OS가 없기 때문에 gcc를 사용하여 ELF 형식의 커널을 컴파일하지 않으면 (여전히 부트 로더가 필요합니다.) 귀하의 이진을 실행하십시오 – sehe

+0

내가 grub을 사용하고 있습니다 – geek1000

+0

그래서 이것은 기본적으로 구문 질문입니까? –

답변

2

내가 이것을 테스트하지했지만, 당신이 시작할 수 있어야합니다

void set_video_mode (int x, int y) { 
    register int ah asm ("ah") = x; 
    register int al asm ("al") = y; 

    asm volatile ("int $0x10" 
       : /* no outputs */ 
       : /* no inputs */ 
       : /* clobbers */ "ah", "al"); 
} 

내가 예를 들어 두 개의 '내리 쳤을 때'에 넣어했지만, 당신의 정확한 목록을 설정해야합니다 clobbers 그래서 컴파일러는 레지스터 값을 덮어 썼다는 것을 안다.

+0

다시 살펴보면 ... 두 int는'volatile' 컴파일러가 그들을 최적화하지 못하도록 막는다. 유의하십시오. – ams

+0

또한 어셈블러 구문이 잘못되었습니다. –

+0

@IsmaelLuceno x86 어셈블러가 어떤 모습인지 확신 할 수 없습니다. (주로 ARM 용으로 사용합니다). 대답의 요점은 C "asm"구문입니다. 나는 그것을 다른 답변들처럼 보이도록 편집했습니다. 그게 더 좋은가요? – ams

0

먼저 GCC는 16 비트 코드를 지원하지 않으므로 16 비트 모드에서 32 비트 코드를 컴파일하게됩니다. 이는 매우 비효율적이지만 실행 가능합니다 (예 : , 리눅스와 SeaBIOS에 의해). 각 파일의 구걸에 다음과 같이 수행 할 수 있습니다

__asm__ (".code16gcc"); 

최근 GCC 버전 (4.9 IIRC 이후) 같은 일을 수행하는 -m16 플래그를 지원합니다.

init_mouse 커널을 실행하기 전에 마우스 드라이버를로드하지 않으면 사용할 수있는 마우스 드라이버가 없습니다.

여러 x86 DOS에서 일반적으로 사용 가능한 API를 사용하는 것 같습니다.

asm 레지스터 할당을 돌볼 수 있으므로 코드가 감소 될 수있다 : 충분한 깊이 아마도되지는 않았지만,

void set_video_mode(int mode) 
{ 
    mode &= 255; 
    __asm__ __volatile__ (
     "int $0x10" 
     : "+a" (mode) /* %eax = mode & 255 => %ah = 0, %al = mode */ 
    ); 
} 

void init_mouse(void) 
{ 
    /* XXX it is really important to check the IDT entry isn't 0 */ 
    int tmp = 0; 
    __asm__ __volatile__ (
     "int $0x33" 
     : "+a" (tmp) /* %eax = 0*/ 
     :: "ebx" /* %ebx is also clobbered by DOS mouse drivers */ 
    ); 
} 

asm 문이 GCC 설명서에 설명되어 있습니다 및 x86 예를 없다. 출력 (첫 번째 콜론 뒤에)은 명확하지 않은 구문을 사용하고 나머지는 이해하기 쉽습니다 (두 번째 콜론은 입력을 지정하고 세 번째는 클럭 된 레지스터, 플래그 및/또는 메모리를 지정합니다).

출력은 접두어로 =이어야합니다. 즉, 이전 값이 마음에 들지 않아야 함을 의미하거나 +을 입력으로 사용하려는 것입니다. 이 컨텍스트에서는 값이 인터럽트에 의해 수정되고 clobbered 목록에 입력 레지스터를 지정하지 못하기 때문에 (컴파일러에서 사용할 수 없으므로) 대신 입력을 사용합니다.

관련 문제