실행 파일이 CPU가 아닌 OS에 의존하는 이유는 무엇입니까?


16

C 프로그램을 작성하여 .exe파일로 컴파일하면 파일 .exe에 CPU에 대한 원시 시스템 명령어가 포함됩니다. (생각합니다).

그렇다면 최신 버전의 Windows를 실행하는 컴퓨터에서 컴파일 된 파일을 어떻게 실행할 수 있습니까? 각 CPU 제품군에는 다른 명령어 세트가 있습니다. 그렇다면 적절한 OS를 실행하는 컴퓨터는 .exe실제 CPU에 관계없이 내 파일 의 지시 사항을 이해할 수 있습니까?

또한 일부 응용 프로그램의 "다운로드"페이지에있는 웹 사이트에서는 종종 Windows, Linux 및 Mac 용 다운로드 (각 OS, 86 및 64 비트 컴퓨터 용으로 두 번의 다운로드)를 다운로드합니다. 각 CPU 제품군에 대해 더 많은 다운로드가없는 이유는 무엇입니까?


4
CPU에는 x86, 64b 등과 같은 표준이 있습니다. 실행 파일은 CPU에 따라 다릅니다. RISC와 같은 특수 CPU에서 언급 한 exe를 실행할 수 없으며, 특수 목적 CPU도 풍부합니다.
InformedA

OS는 실행 파일로 구성되며 OS이기 때문에 OS가 아닌 CPU에 의존합니다.
Tulains Córdova

이전 버전과의 호환성으로 인해.
MiKL

2
86 및 64 비트 컴퓨터의 경우 각 OS에 대해 두 번의 다운로드가 종종 발생 합니다. CPU에서 실행 파일의 종속성으로 해석합니다.
mouviciel

답변:


37

실행 파일은 OS와 CPU에 따라 다릅니다.

  • 명령어 세트 : 실행 파일의 이진 명령어는 일부 명령어 세트에 따라 CPU에 의해 디코딩됩니다. 대부분의 소비자 CPU는 x86 ( "32bit") 및 / 또는 AMD64 ( "64bit") 명령어 세트를 지원합니다. 이러한 명령어 세트 중 하나에 대해 프로그램을 컴파일 할 수 있지만 둘 다 사용할 수는 없습니다. 이러한 명령어 세트에는 확장이 있습니다. 이러한 지원은 런타임에 쿼리 할 수 ​​있습니다. 이러한 확장은 예를 들어 SIMD 지원을 제공합니다. 최적화 컴파일러는 이러한 확장이있는 경우 이러한 확장을 활용하려고 시도하지만 일반적으로 확장없이 작동하는 코드 경로를 제공합니다.

  • 이진 형식 : 실행 파일은 특정 이진 형식을 준수해야하므로 운영 체제에서 프로그램을 올바르게로드, 초기화 및 시작할 수 있습니다. Windows는 주로 Portable Executable 형식을 사용하고 Linux는 ELF를 사용합니다.

  • 시스템 API : 프로그램이 라이브러리를 사용 중일 수 있으며 실행중인 시스템에 있어야합니다. 프로그램이 Windows API의 기능을 사용하는 경우 Linux에서 실행할 수 없습니다. Unix 세계에서 중앙 운영 체제 API는 POSIX로 표준화되었습니다. POSIX 기능 만 사용하는 프로그램은 Mac OS X 및 Solaris와 같은 적합한 Unix 시스템에서 실행될 수 있습니다.

따라서 두 시스템이 동일한 시스템 API 및 라이브러리를 제공하고 동일한 명령어 세트에서 실행하고 동일한 이진 형식을 사용하는 경우 한 시스템 용으로 컴파일 된 프로그램도 다른 시스템에서 실행됩니다.

그러나 호환성을 높이는 방법이 있습니다.

  • AMD64 명령 세트에서 실행되는 시스템은 일반적으로 x86 실행 파일도 실행합니다. 이진 형식은 실행할 모드를 나타냅니다. 32 비트 및 64 비트 프로그램을 모두 처리하려면 운영 체제의 추가 노력이 필요합니다.

  • 일부 이진 형식을 사용하면 파일에 여러 명령 세트를 위해 컴파일 된 여러 버전의 프로그램이 파일에 포함될 수 있습니다. 이러한“지방 바이너리”는 Apple이 PowerPC 아키텍처에서 x86으로 전환하는 동안 장려했습니다.

  • 일부 프로그램은 기계 코드로 컴파일되지 않고 일부 중간 표현으로 컴파일됩니다. 그런 다음이 명령은 즉석에서 실제 명령어로 변환되거나 해석 될 수 있습니다. 이것은 프로그램을 특정 아키텍처와 독립적으로 만듭니다. 이러한 전략은 UCSD p-System에서 사용되었습니다.

  • 하나의 운영 체제가 여러 이진 형식을 지원할 수 있습니다. Windows는 이전 버전과 호환되며 DOS 시대의 형식을 계속 지원합니다. Linux에서 Wine을 사용하면 Windows 형식을로드 할 수 있습니다.

  • 한 운영 체제의 API는 다른 호스트 OS에 대해 다시 구현 될 수 있습니다. Windows에서 Cygwin 및 POSIX 하위 시스템을 사용하여 (대부분) POSIX 호환 환경을 얻을 수 있습니다. Linux에서 Wine은 많은 Windows API를 다시 구현합니다.

  • 크로스 플랫폼 라이브러리를 사용하면 프로그램이 OS API와 독립적 일 수 있습니다. 많은 프로그래밍 언어에는이를 달성하려는 표준 라이브러리 (예 : Java 및 C)가 있습니다.

  • 에뮬레이터 , 외국 바이너리 형식을 구문 분석 지침을 해석하고, 필요한 모든 API를 재 구현을 제공함으로써 다른 시스템을 시뮬레이션합니다. 에뮬레이터는 일반적으로 최신 PC에서 오래된 Nitendo 게임을 실행하는 데 사용됩니다.


10
java와 .net은 모두 중간 형식을 사용하는 예입니다. 중간 형식은 오늘날 매우 인기가 있으며 5 1/4 플로피로 부족한 1970 년대 시스템의 유물이 아닙니다.
jmoreno

@AKoscianski 제안한 편집에 감사드립니다 . 그러나 보안 디자인은 실행 파일이 OS에 의존하는 이유가 아니라 OS 대 사용자 영역이 먼저 분리 된 이유라고 생각합니다. 이러한 보호 된 운영 체제 기능에 대한 다른 API는이 답변의 "시스템 API"섹션에서 이미 해결되었습니다.
amon

2

Windows를 실행하는 현재 PC의 99 %에는 64 비트 프로세서가 있으며 32 비트 소프트웨어도 실행할 수 있습니다. 나머지 1 %에는 32 비트 프로세서가 있습니다. 따라서 32 비트 프로세서 용으로 제작 된 소프트웨어는 모든 곳에서 실행됩니다. 64 비트 프로세서 용으로 제작 된 소프트웨어는 소프트웨어 제작자가 관심을 갖는 모든 PC에서 실행됩니다.

MacOS X 및 iOS는 "지방 바이너리"를 지원합니다. 실제로 다운로드 한 파일에는 다른 프로세서 용 버전이 포함될 수 있습니다. 더 이상 PowerPC 프로세서 용 응용 프로그램을 구축하는 사람은 없지만 몇 년 전 실행 파일에는 PowerPC, 32 비트 Intel 및 64 비트 Intel 버전이 포함되어있을 수 있으며 올바른 것이 실행됩니다. 요즘 iOS에서는 앱을 다운로드하면 기기의 프로세서에 적합한 버전이 제공됩니다. 다른 장치에서 다운로드하면 다른 버전이 제공됩니다. 사용자에게는 전혀 보이지 않습니다.


-1

exe는 원시 머신 코드보다 더 많은 정보를 포함합니다. OS는로드 할 때이를 읽고 실행 방법을 알아낼 수 있습니다.

컴파일 할 때 일반적으로 대상 CPU를 설정하면 컴파일러가 현재 CPU를 선택하지 않고 CPU와 이전 버전의 CPU에 공통적 인 명령 만 선택하도록 제한합니다. 대상 CPU의 특정 버전에 특정한 새롭고 멋진 명령어를 사용하려면 컴파일러에 지시하거나 내장 또는 인라인 어셈블리 코드를 사용하여 수동으로 코딩 할 수 있습니다. 그러나 해당 명령을 지원하지 않는 CPU에서 프로그램을 실행하면 프로그램이 중단됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.