2014-07-24 3 views
2

64 비트 리눅스에서 간단한 프로그램으로 __NR_exit을 인쇄 할 경우 값은 <asm/unistd_64.h>에 정의 된대로 60입니다. 그러나, (-nostdlib 컴파일)이 코드는 세그먼테이션 폴트 (segfault) : __NR_exit<unistd.h>unistd.h 상수 linux x86_64

의 32 비트 버전 1로 정의된다

void _start(){ 
asm("movl $1,%eax;" 
    "xorl %ebx,%ebx;" 
    "int $0x80"); 
} 

을 :

void _start(){ 
asm("movl $60,%eax;" 
    "xorl %ebx,%ebx;" 
    "int $0x80"); 
} 

을하지만,이 예상대로 실행 분명히 1이 정확한 상수입니다. 32 비트 syscall 값이 사용되는 이유는 무엇입니까?

$ uname -a           
Linux galois 3.14.6-1-ARCH #1 SMP PREEMPT Sun Jun 8 10:08:38 CEST 2014 x86_64 GNU/Linux 

답변

2

x86-64 시스템의 호출 규칙이 다릅니다. Linux는 호출 규칙을 포함하는 System V ABI를 채택했습니다.

시스템 콜 번호 %rax에 저장하고, 인수를 순서대로 %rdi, %rsi, %rdx, %r10, %r8%r9에 따라, 상기 지시 syscallint $0x80 대신 사용된다. MEMORY 클래스에 속하는 것으로 분류 된 정수 및 항목 만 전달할 수 있으며 해당 레지스터 만 사용할 수 있습니다. 클래스 MEMORY의 항목은 스택을 통해 전달됩니다. 시스템 콜에 6 개의 인수 또는 그 이하를 전달할 수 있습니다.

사용자 모드 기능 대신 %r10으로 사용되는 %rcx 제외하고, 제 1 함수 인수 %rdi에 저장되면서 동일한 레지스터를 사용하여 호출되며, %rax는 콜 번호 대신 전달 SSE 인수의 수를 나타내는 데 사용되는 .

자세한 내용은 System V AMD64 Calling Convention을 참조하십시오. 그러나 일부 Linux 관련 정보에 대한 자세한 내용은 부록 A의 하위 섹션 the actual specification에서 찾을 수 있습니다.

관련 문제