2014-08-30 6 views
4

나는 함수 내에서 코드를 아래이 있습니다 GCC 인라인 어셈블리 "asm '피연산자에는 불가능한 제약 조건이 있습니까?

void makeSystemCall(uint32_t num, uint32_t param1, uint32_t param2, uint32_t param3){ 
    asm volatile (
     "mov %0, %%eax\n\t"//Move num to eax 
     "mov %1, %%ebx\n\t"//Move param1 to ebx 
     "mov %2, %%ecx\n\t"//Move param2 to ecx 
     "mov %3, %%edx\n\t"//Move param3 to edx 
     "int $0x80"//Call interrupt. Data in eax, ebx, ecx and edx 
     : //No output params 
     : "r" (num), "r" (param1), "r" (param2), "r" (param3)//Input params 
     : "%eax", "%ebx", "%ecx", "%edx" //This handles register state pushing and popping? 
    ); 
} 

지금 나는이 작동하지 않는 이유를 모르겠어요. GCC는 말한다 : "오류 : 'ASM'피연산자가 불가능 제약이있다"나는 GCC 인라인 어셈블리 자습서를 다음되었으며, 그래도 난이 조립 블록을 인라인 C 코드에서 매개 변수를 사용하는 올바른 방법이 될 것이다.

또한 나는 32 비트 x86 용 내장의 gcc 크로스 컴파일러를 사용합니다. 은 "R"제약 조건을 사용하여

+0

그렇게하지 마십시오. 사용 가능한 [콜 (2)] (http://man7.org/linux/man-pages/man2/syscalls.2.html) 또는 간접 필요한 경우 [콜을 (2)] (HTTP : // man7 .org/linux/man-pages/man2/syscall.2.html). 그들은 [VDSO] (https://en.wikipedia.org/wiki/VDSO)를 사용하므로 더 빠를 것입니다. –

+0

@BasileStarynkevitch 만약 내가 신경 쓸 필요가 없다면, 여기에 내 자신의 OS를 좀 개발하고있다. –

+0

그런 다음 기존의 libc를 포트에 연결하려고 시도한다. [musl-libc] (http://musl-libc.org/)에는 매우 쉽게 읽을 수있는 소스 코드가 있습니다. 그리고'SYSENTER' 기계 호출을 사용하십시오. –

답변

8

mov 지시 사항 중 하나에 해당 스크래치 레지스터를 사용하기 전에 스크래치 레지스터에 매개 변수를로드하도록 컴파일러에 강제로. 단순히 4 개의 스크래치 레지스터를 사용할 수 없습니다.

대신 "g"제약 조건을 사용합니다. 이것은 컴파일러가 스크래치 레지스터로 프레임 포인터를 오프셋 한 다음 최종 레지스터로 스크래치 레지스터를 옮기는 대신 오프셋 레지스터로 메모리 액세스를 사용하여 mov 명령어에서 직접 인수에 액세스 할 수 있기 때문에 더 효율적입니다.

+0

감사합니다. 'r'을'g'로 바꾸면 매력처럼 작동합니다. D. –