FreeBSD와 Linux: 커널 호출 규칙의 성능

FreeBSD와 Linux: 커널 호출 규칙의 성능

에서int80h.org, FreeBSD 어셈블리 언어 튜토리얼

[리눅스 호출] 규칙은 적어도 어셈블리 언어 프로그래밍에 관한 한 Unix 방식에 비해 큰 단점이 있습니다. 커널 호출을 할 때마다 레지스터를 푸시한 다음 나중에 팝해야 합니다. 이로 인해 코드가 더 커지고 느려집니다.

계속해서 Linux 규칙과 "Unix 규칙"을 모두 지원하는 FreeBSD에 대해 설명합니다.

FreeBSD용으로 특별히 코딩하는 경우 항상 Unix 규칙을 사용해야 합니다. 더 빠르고 전역 변수를 레지스터에 저장할 수 있으며 실행 파일에 브랜드를 지정할 필요가 없으며 Linux 에뮬레이션 패키지 설치를 강요하지 않습니다. 대상 시스템.

Linux 방식이 더 크고 느리다는 것이 이상하게 보입니다. 선택지는 2가지인 것 같은데,

  • 보존해야 할 레지스터만 저장하십시오.
    • ecx(내가 아는 한 ) 시스템 호출에 의해 방해받을 수 있는 휘발성 레지스터
    • 또는 레지스터는 커널에 적절한 인수를 전송하여 ( , , , , , syscall일 수 있음 )eaxecxedxesiediebp
  • 스택의 커널에 대한 인수를 100% 저장합니다.

FreeBSD가 그런 것 같습니다.최악의Linux 컨벤션의 사례 시나리오. 내가 무엇을 놓치고 있나요? FreeBSD 규칙("Unix 방식"이라고 함)은 어떻게 덜 부피가 크고 더 빠릅니까?

답변1

내 생각에는 이것은 실제로 저자의 의견으로 귀결됩니다.

FreeBSD("Unix") 규칙에서는 스택에 인수를 푸시하고 에 시스템 호출 번호를 지정 EAX하고 인터럽트 0x80을 호출합니다(별도의 함수에서 호출될 것으로 예상되므로 스택에 추가 피연산자를 사용하여).

Linux i386 규칙에서는 인수를 적절한 레지스터에 배치하고 인터럽트 0x80을 호출합니다.

부피가 크다/느리다는 주장은 아마도 Linux 컨벤션에서는방문객레지스터 사용을 처리해야 합니다. 시스템 호출이 호출자가 관심을 갖는 값을 포함하는 레지스터에 인수를 필요로 하는 경우 이를 보존해야 하므로 추가적인 발품이 필요합니다.C 라이브러리에서 이 예제를 참조하세요.. 이 예에서 시스템 호출에는 EAX, EBX, EDX, EDI 및 ESI의 값이 필요합니다. 그러나 호출자는 EBX, EDI 및 ESI 보존에만 관심이 있으므로 해당 항목만 스택에 푸시합니다. 일반적인 경우는좀 더 복잡하다(그러나 이는 C와 어셈블리 언어의 혼합을 처리하고 모든 경우에 최적의 코드를 생성하려고 시도한 결과이기도 합니다.) 그러나 참조하는 사이트의 요점인 어셈블리 언어로 작성할 때는 그렇지 않습니다. 그다지 문제가 되지는 않습니다.

제가 보기엔 66개 정도인 것 같습니다. FreeBSD 규칙에서는 모든 경우에 스택으로 푸시하고, Linux 규칙에서는 수행 중인 작업에 따라 스택(또는 다른 곳)으로 푸시합니다. 통화 사이트. 모든 계산을 레지스터에서 수행할 수 있으므로 Linux 규칙을 사용하면 코드 속도가 더 빨라진다고 주장할 수도 있습니다.그러나 Linux에서는 레지스터가 여전히 푸시되기 때문에( struct pt_regs시스템 호출을 처리하는 C 함수에 인수를 제공하는 데 사용되는 인스턴스를 구축하기 위해) 전체 비용은 Linux 측에서보다 더 큽니다. FreeBSD 측.

어쨌든 시스템 호출과 관련된 스택 또는 레지스터 기반 코드에 대해 이야기할 때 성능에 대해 논쟁하는 것은 시스템 호출 자체를 수행하는 데 드는 비용을 고려할 때 다소 현학적으로 보입니다. 저장된 사이클은 물론 절대적인 측면에서는 좋지만 상대적인 개선 효과는 미미합니다.

관련 정보