32비트 코드가 64비트 공유 라이브러리를 사용할 수 없는 이유는 무엇입니까?

32비트 코드가 64비트 공유 라이브러리를 사용할 수 없는 이유는 무엇입니까?

GNU/Linux, x86/x86-64에서 일반적으로(적어도 때로는 예외가 있을 수 있음) 32비트 프로그램에서 64비트 라이브러리 코드를 사용할 수 없는 이유는 무엇입니까?

나는 x86-64와 x86 사이의 많은 차이점, 긴 모드, 확장 레지스터, 새 레지스터, 세그먼트 제거(어느 정도)를 알고 있습니다.

하지만 그게 왜 중요할까요? Long 모드의 권한 있는 코드와 관련된 변경 사항은 커널 모드에서 실행되지 않는 한 시스템 라이브러리에 적용되지 않습니다.

사용자 영역 변경, 더 큰 레지스터, 새로운 레지스터 등이 왜 중요한가요? 64비트 시스템에서 CPU는 사용자 공간에 들어갈 때 이미 롱 모드에서 실행 중이고 이 경우 롱 모드는 이전 버전과 호환되므로(보호 모드로 전환하지 않고도) 32비트 모드 비트를 사용할 수 있어야 합니다. 사용자 공간에 있는 64비트 코드.

여기서 분명한 것을 놓치고 있습니까?

물론 64비트 라이브러리에 다른 API가 있거나 다른 이름이 있는 경우 예를 들어 실행하면 ldd32비트 라이브러리와 다른 이름을 가진 공유 라이브러리를 찾고 있는 것으로 나타날 수 있습니다. 그것은 문제가 될 것입니다. 그게 전부라면 해결책(패치워크라도)은 꽤 쉬울 것입니다.

x86-64 호출 규칙이 일반 x86과 다르기 때문에 라이브러리에서 함수를 호출하는 것조차 문제가 될 것이라고 상상할 수도 있습니다. 확실히 이것이 문제의 일부입니까?

하지만 여기에는 더 나은 이유가 있어야 할 것 같고, 제가 뭔가 분명한 것을 놓치고 있는 것 같습니다.

답변1

x86-64 프로세서는 자신이 구현하는 호환 모드를 통해서만 32비트 x86 프로세서와 역호환됩니다. 긴 모드의 x86-64에 대한 대부분의 명령어는 ia-32 명령어와 동일하므로 레지스터의 위쪽 절반을 무시하여 어느 정도 호환성을 얻을 수 있습니다. 그러나 차이점이 있으며 일부 ia-32 명령(예: 짧은 점프)이 x86-64 긴 모드에서 제거되었습니다. 64비트 및 32비트 x86은 서로 다른 명령어 세트를 효과적으로 구현합니다.

프로세서를 호환 모드로 전환하면 x86-64 CPU에서 32비트 코드만 실행할 수 있으며 그 반대의 경우도 마찬가지입니다. 32비트 호환 모드에서 64비트 라이브러리 코드를 호출하려면 호환 모드에서 64비트 긴 모드로 전환해야 합니다. 모드는 코드 조각 설명자의 비트에 의해 결정되므로 긴 모드와 호환 모드의 코드에 대해 별도의 코드 조각을 설정해야 합니다. 예를 들어, 호환 모드에서 CPU는 하위 4GB의 가상 주소 공간만 볼 수 있는 등 몇 가지 고려해야 할 사항이 있습니다.

관련 정보