2013-03-24 3 views
8

MS-DOS 이후로 인터럽트를 사용하는 시스템 호출을 알고 있습니다. 예전의 문서에서는 리눅스에서 시스템 기능을 호출하기 위해 int 80h에 대한 참조를 보았습니다. 오랜 시간이 걸린 지금부터 syscall 명령어를 사용하여 int 80h을 사용하지 않습니다. 하지만 내 32 비트 컴퓨터에서 작동시키지 못합니다.32 비트 시스템의 Syscall 또는 sysenter Linux?

질문

는 64 비트 플랫폼에서 사용되는 syscall 명령인가? 32 비트 리눅스가 syscall을 사용하지 않습니까?

샘플 테스트 내 32 비트 리눅스 (우분투 정밀)에

,이 프로그램은 코어 덤프로 종료 : 내가 대신 syscallsysenter으로 시도했습니다

global _start 

_start: 
     mov  eax, 4    ; 4 is write 
     mov  ebx, 1    ; 1 is stdout 
     mov  ecx, message   ; address of string 
     mov  edx, length   ; number of bytes 
     syscall 

     mov  eax, 1    ; 1 is exit 
     xor  ebx, ebx    ; return code 0 
     syscall 

message: 
     db 10,"Hello, World",10,10 
length equ $ - message 

,하지만 충돌 같은 길.

+0

[int "0x80"또는 "syscall"이 무엇인가요?] (http://stackoverflow.com/questions/12806584/what -is-better-int-0x80-or-syscall) – Michael

+1

실제로 여기 뭔가 관련이 있습니다. (http://stackoverflow.com/a/12806910/279335), 큐에 응답하지 않습니다. stion. 인텔의 32 비트 모드에서는'syscall '을 사용할 수 없지만 어셈블러는 이것을 32 비트 모드로 컴파일했다. 어설 션이 불분명하거나 잘못되었습니다. 그런 다음 불법적 인 명령으로 인해 코어 덤프가 발생하지만이 명령어는 Pentium II로 시작하는 모든 Intel CPU에서 사용할 수 있으며 그 이상입니다. 그는'sysenter'에 대해서 언급했는데, 나는 같은 결과로 시도했다. 어쨌든 리눅스 ABI에서는'sysenter'에 대해서는 언급하지 않았고'int 80h' 또는'syscall' 만 보았습니다. – Hibou57

+2

글쎄, "[System Calls (wiki.osdev.org) (http://wiki.osdev.org/System_Calls)"에 따르면,'syscall'은 인텔의'sysenter'에 해당하는 AMD입니다. "인텔 CPU에서 펜티엄 II부터 새로운 명령어 쌍 sysenter/sysexit가 등장했습니다. 모드 변경의 오버 헤드를 제한하여 사용자 모드에서 커널 모드로 신속하게 전환 할 수 있습니다. ** 유사한 명령 쌍이 AMD에 의해 만들어졌습니다 : Syscall/Sysret **. 그러나이 명령어의 동작은 Intel의 것과 다릅니다. * " – Hibou57

답변

5

일부 웹 검색 후 StackOverflow에서이 다른 주제 인 : Linux invoke a system call via sysenter tutorial에 도착했습니다. 시스템을 호출하는 권장 방법은 int 80h도 아니고 syscall도 아니고 sysenter도 아니고 linux-gate.so입니다.

여전히 충돌 및 코어 덤프에 대한 질문이 남아 있습니다. 내 생각에 마침내 12834 명령어는 CPU 명령어로 사용할 수 있지만 리눅스 커널은 주어진 하드웨어 플랫폼에서 실제로 유용하지 않다고 결정할 때이 "진입 점"을 올바르게 설정하지 않을 수도 있습니다. 그것은 단지 64 비트 플랫폼에서 항상 사용할 수있는 동안

는, 32 비트 플랫폼, sysenter 또는 syscall 사용할 수 있습니다에 보인다.

나는이 대답을 내 질문으로 생각하지만, 나는 여전히 위의 추측에 대한 권위있는 참고 자료처럼 더 많은 자료를 환영합니다.

- 업데이트 -

적어도 위 내용을 확인할 수 있습니다. 그것은 여전히 ​​권위있는 참고서는 아니지만 충분히 믿을만한 것 같습니다.

What is linux-gate.so.1?는 말한다 :

시스템 콜을 호출의 선호하는 방법은 부팅시에 커널에 의해 결정 및 입니다 분명이 상자 sysenter를 사용합니다. linux-gate.so 통해 시스템 함수를 호출,

또한, 다른 소스에서, 샘플 FASM 어셈블리 소스는 (당신이 NASM을 사용하는 경우 일부 번역이 필요) : Finding linux-gate.so.1 in Assembly는.

+1

sysenter/syscall을 사용할 때, 규약은 int 0x80을 사용하는 것과 동일한 entierly가 아닐 수 있습니다. 'sysenter'의 경우 iirc,'push ecx push edx push ebp mov ebp, esp'가'sysenter' 바로 앞에 있습니다. – nos

+1

커널은 부팅시''커널에 의해 결정됩니다. int 80 , sysenter 또는 syscall을 사용하십시오. Int 80은 항상 작동하지만 느리고 새로운 CPU에서는 sysenter 또는 syscall 중 하나만 작동합니다. 프로그램이 선택해야하는 것은 아니며, 커널이 최적의 선택을합니다. –

5

Intel manual은 호환성 (32 비트) 모드에서 syscall이 유효하지 않으므로 커널에서 사용해서는 안됩니다.

그러나 이것은 인텔 전용 제한 될 것으로 보인다 : https://stackoverflow.com/a/29784932/895245 AMD는 없지만, 확실히 리눅스는

sysenter가 그대로 오늘 그것을 할 수있는 가장 좋은 방법이 될 것으로 보인다 :-) 인텔을 지원해야 int 0x80보다 빠르지 만, 설명 된대로 VDSO를 통해 간접적으로 사용해야합니다.

+1

누군가가 초기 질문에 대한 의견을 제기했습니다. 나는 경고없이 사용 된 어셈블러에 의해 컴파일 된 명령에 응답하고 opcode는 32 비트 용으로 문서화되었다. 아마도 이것은 64 비트 아키텍처의 32 비트 모드에서만 유효하지 않을 수 있습니다 ... 어쨌든, 당신이 말했듯이 리눅스의 맥락에서 VDSO (Glibc 없이도 검색 할 수있는 방법이 있습니다)에 의존하는 것이 좋습니다. – Hibou57

+1

@ Hibou57 : [이 메모 스레드] (http://stackoverflow.com/questions/38063529/x86-32-x86-64-polyglot-machine-code-fragment-that-detects-64bit-mode-at- run-ti/38063530? noredirect = 1 # comment63566180_38063530) : AMD CPU에서만 32 비트 모드로 유효합니다. 나는 그것이 32 비트 코드에서 어셈블 및 디스 어셈블된다는 것에 놀랐지 만 분명히 AMD는 AMD64 아키텍처와 별도로 (그리고 어쩌면) 시스템 콜을 도입했습니다. 인텔의 지시가 32 비트 모드 (평소와 같이)를 얻었지만 AMD는 AMD64의 표준이되었습니다. –

관련 문제