it-source

32비트 응용 프로그램은 64비트 Linux에서 시스템 호출을 어떻게 합니까?

criticalcode 2023. 10. 28. 08:00
반응형

32비트 응용 프로그램은 64비트 Linux에서 시스템 호출을 어떻게 합니까?

일부 64비트1 리눅스 배포판은 32비트 및 64비트 라이브러리(libc 포함)의 병렬 컬렉션을 제공하여 32비트 응용 프로그램을 실행할 수 있도록 합니다.따라서 32비트 응용프로그램은 32비트 lib에 링크할 수 있고 64비트 커널로 실행될 수 있습니다.

32비트 응용 프로그램이 64비트 커널에서 시스템 호출을 하는 방법에 대한 메커니즘을 알고 싶습니다.답이 libc나 커널 소스 어딘가에 있다고 생각하지만, 어디를 찾아야 할지 몰라서 소스에 뛰어들기에는 시간이 많이 걸릴 것 같습니다.

그리고 더 중요한 질문은 성능 오버헤드가 있습니까?2논리적으로 32비트 앱 시스템 호출에서 오는 호출은 64비트 내부 커널 환경으로 변환되어야 합니다.이것은 어떻게 그리고 어디서 이루어집니까?

"32비트" = IA-32, "64비트" = AMD64
2 당신의 답변에서 그것이 중요하다고 가정하세요 :)

사용자 공간 측면에서, 그 메커니즘은 32비트 네이티브 커널에서 시콜을 하는 것과 동일합니다 - 32비트 glibc를 포함한 모든 사용자 모드 코드는 동일한 방식으로 작동합니다.

커널 측면에서 볼 때, 오래된 IA32 엔트리는 사용자 공간(예:int 0x80를 호출하도록 설정되어 있습니다.ia32_syscall조립공 일(커널 공간으로의 전환은 프로세서가 커널의 코드 세그먼트 셀렉터를 로드하는 것을 수반하며, 이로 인해 64비트 "롱" 모드로 전환됩니다.)

ia32_syscall그런 다음 routine은 x86_64 syscall 호출 규약과 일치하도록 몇 가지 인수를 섞습니다.

movl    %edi,%r8d
.if \noebp
.else
movl    %ebp,%r9d
.endif
xchg    %ecx,%esi
movl    %ebx,%edi
movl    %edx,%edx   /* zero extension */

그런 다음 IA32 syscall 번호를 사용하여 테이블을 통해 함수 호출을 합니다.ia32_sys_call_table. 이는 기본적으로 IA32 syscall 번호를 기본 syscall 구현과 일치시킵니다(syscall 번호는 IA32와 x86_64 간에 크게 다름).이 표의 첫 번째 부분은 다음과 같습니다.

ia32_sys_call_table:
    .quad sys_restart_syscall
    .quad sys_exit
    .quad stub32_fork
    .quad sys_read
    .quad sys_write

대부분의 syscall의 경우 x86_64 구현을 직접 호출할 수 있습니다.exit(). 다른 사람들을 위해, 예를 들어,fork(), 예상되는 IA32 시맨틱스(특히 32비트에서 64비트로 인수의 부호 확장이 필요한 경우)를 올바르게 구현하는 래퍼가 제공됩니다.

보시다시피 커널 코드의 오버헤드는 최소입니다. 값을 등록하기 위한 몇 가지 사소한 수정과 몇 가지 함수에 대한 추가 함수 호출입니다.32비트 모드에서 64비트 모드로 전환하는 코드 세그먼트 선택기를 로드하는 것이 프로세서가 실행하는 것보다 느리는지 확실하지 않습니다. 프로세서 아키텍처 설명서를 확인해 보십시오.

언급URL : https://stackoverflow.com/questions/3305350/how-do-32-bit-applications-make-system-calls-on-64-bit-linux

반응형