C는 표준 ABI를 가지고 있습니까?
다른 곳에서 논의한 내용:
C++에는 표준 ABI(Application Binary Interface)가 없습니다.
하지만 C도 마찬가지야, 그치?
모든 플랫폼에서 거의 동일한 성능을 발휘합니다.그것이 부족하다면 언어 간 의사소통을 위한 언어 프랑카로서 유용하지 않을 것입니다.
이 건에서 당신 수익은 얼마나 됩니까?
C는 ABI를 정의하지 않습니다.사실, 그것은 ABI를 정의하지 않기 위해 뒤로 구부립니다.8비트 바이트, 2의 보완 산술 및 플랫 주소 공간을 가진 16/32/64비트 아키텍처에서 프로그래밍 인생의 대부분을 C에서 보낸 저와 같은 사람들은 보통 현재 C 표준의 복잡한 언어를 읽는 데 상당히 놀랄 것입니다.
예를 들어 포인터에 대한 내용을 읽습니다.표준은 ABI에 대해 가정하는 것에 대해 "포인터는 주소입니다"와 같은 간단한 것을 말하지 않습니다.특히 포인터가 서로 다른 주소 공간에 있고 다양한 너비를 가질 수 있습니다.
ABI는 언어의 실행 모델에서 특정 시스템/운영 체제/컴파일러 조합으로의 매핑입니다.언어 사양에서 하나를 정의하는 것은 말이 안 됩니다. 일부 아키텍처에서 C 구현을 제외할 위험이 있기 때문입니다.
C에는 원칙적으로 표준 ABI가 없지만 실제로는 거의 중요하지 않습니다.OS 공급업체가 수행하는 작업을 수행합니다.
x86 Windows에서 호출 규칙을 예로 들 수 있습니다.Windows API는 이른바 '표준' 호출 규약(stdcall)을 사용합니다.따라서 OS와 인터페이스하려는 컴파일러는 이를 구현해야 합니다.그러나 stdcall이 모든 C90 언어 기능(예: 프로토타입이 없는 호출 기능, 가변 기능)을 지원하지는 않습니다.마이크로소프트가 C 컴파일러를 제공했기 때문에 'C' 호출 규칙(cdecl)이라고 하는 두 번째 호출 규칙이 필요했습니다.윈도우즈의 대부분의 C 컴파일러는 이를 기본 호출 규약으로 사용하므로 상호 운용이 가능합니다.
할 수 포함)가더 정교하기 C++ ABI, C++ ABI(호출 규약 포함)로 할 수 . 다음으로 돌아가서 상호 운용할 수 있었습니다.extern "C"
.
C에 대한 ABI는 플랫폼에 따라 다릅니다. 특정 프로세서에 특정한 레지스터 할당 및 호출 규칙과 같은 문제를 다룹니다.다음은 몇 가지 예입니다.
- ARM ABI(C++ 포함)
- PowerPC 임베디드 ABI
- x86의 여러 ABI
x86은 윈도우 아래에서 어떤 것이 사용되는지를 선언하기 위해 확장되는 많은 호출 규칙을 가지고 있습니다.임베디드 리눅스용 플랫폼 ABI도 시간이 지남에 따라 변경되어 사용자 공간이 호환되지 않습니다.여기에서 ARM Linux 포트의 일부 내역을 참조하십시오. 이 포트는 최신 ABI로 전환할 때 발생하는 문제를 보여줍니다.
여러 운영 체제(특히 유닉스 시스템즈의 i386용)에 걸쳐 특정 아키텍처에 대해 단일 ABI를 정의하는 시도가 여러 차례 있었지만, 이러한 노력은 성공을 거두지 못했습니다.대신 운영 체제는 자체 ABI를 정의하는 경향이 있습니다.
C의 경우에도 ABI는 플랫폼에 매우 독립적인 부품을 가지고 있습니다. 프로세서에 의존하는 부품입니다. (어떤 레지스터를 저장해야 하는지, 매개 변수를 전달하는 데 사용되는지...)OS에 의존하는 부분들 (일부 선택은 아키텍처에 의해 강요되지 않지만 트레이드오프의 결과로서 프로세서와 다소 동일한 요소들), 그리고 일부 OS는 언어 독립적인 예외 개념을 가지고 있기 때문에 모든 언어에 대한 컴파일러는 이러한 것들을 처리하기 위해 올바른 것을 생성해야 합니다.스레드 처리는 또한 ABI에 무언가를 부과할 수 있습니다. 레지스터가 TLS를 가리킬 경우 원하는 용도로 사용할 수 없습니다.)
이론적으로 모든 컴파일러는 자체 ABI를 가질 수 있습니다.그러나 일반적으로 커플 프로세서/OS의 경우 ABI는 C 컴파일러와 경쟁사들이 선호하는 호환성을 사용하는 공통 라이브러리를 제공하는 OS 벤더에 의해 고정됩니다. (C가 주요 프로그래밍 언어가 아닌 일부 OS에 예외가 있다고 해도 놀라지 않습니다.)
그러나 OS 공급업체는 한 가지 이유로 ABI를 전환할 수 있습니다(예를 들어 일부 프로세서는 모든 레지스터를 사용할 수 있는 x86_64용 32비트 ABI를 요청했습니다).마이그레이션 단계 중(매우 오랜 시간이 걸릴 수 있음)에는 두 개의 ABI를 처리해야 할 수도 있습니다.
C도 마찬가지죠, 그렇죠?
요.
모든 플랫폼에서 거의 동일한 성능을 발휘합니다.그것이 부족하다면 언어 간 의사소통을 위한 언어 프랑카로서 유용하지 않을 것입니다.
C 컴파일러 공급업체가 선택한 아키텍처별 기본값이 다른 언어로 조정되는 것을 의미할 수 있습니다.따라서 Keil의 ARMC 컴파일러가 왼쪽에서 오른쪽으로 작은 엔디안 매개 변수 순서와 스택을 사용하여 인수와 반환 값에 대한 미리 결정된 레지스터를 전달한다면, 다른 컴파일러의 외부 "C"는 이러한 체계와의 호환성을 가정할 것입니다.
이러한 계약은 JVM 브라우저 샌드박스와 같은 관리형 실행 컨텍스트와 달리 ABI의 일부로 간주될 수 있지만, 이 자체로는 완전한 표준 ABI와는 거리가 멉니다.
C에는 표준 ABI가 없습니다.이는 외부에서 사용되는 모든 호출 규칙(cdecl, fastcall 및 stdcall)에서 쉽게 설명할 수 있습니다.각각은 다른 ABI입니다.
C89 Standard 이전에는 데이터 크기의 변화를 제외하고 많은 플랫폼의 C 컴파일러가 기본적으로 동일한 ABI를 사용했습니다.스택이 아래로 증가하는 머신의 경우 함수를 호출하는 코드는 스택의 인수를 오른쪽에서 왼쪽으로 푸시한 다음 함수를 호출합니다(프로세스에서 반환 주소 푸시).호출된 함수는 스택에 인수를 남기고 호출자는 여유 시간에 스택 포인터를 조정하여 제거합니다(또는 일부 아키텍처에서는 스택 값을 조정할 수 있음).하는 동안에<stdarg.h>
대부분의 프로그램들이 그 관습에 의존하는 것을 불필요하게 만들었습니다, 그것은 단순하고 꽤 잘 작동했기 때문에 수년 동안 사용되었습니다.크로스 플랫폼의 "표준"이라는 것을 입증하는 "공식" 문서는 없었지만, 하향식 스택이 있는 컴퓨터를 대상으로 하는 대부분의 컴파일러는 그러한 방식으로 작동하여 현재보다 더 높은 수준의 일관성을 얻었습니다.
C는 항상 최대 런타임 성능에 관한 것이었고 가장 높은 성능을 가진 ABI는 기본 하드웨어에 의존하기 때문에 표준 ABI는 없습니다.결과적으로, ABI는 주어진 하드웨어에 필요한 함수 호출 인수와 반환 값을 전달하기 위해 스택 또는 선호 레지스터만 사용할 수 있습니다.
예를 들어, amd64(일명 x86-64)에도 두 가지 호출 규칙이 있습니다.마이크로소프트 x64 및 시스템 V AMD64 ABI.전자는 4개의 첫 번째 인수를 레지스터에 넣고 나머지는 스택에 넣습니다.후자는 6개의 첫 번째 인수를 레지스터에 넣고 나머지는 스택에 넣습니다.마이크로소프트가 왜 amd64 하드웨어에 대해 호환되지 않는 호출 규약을 만들었는지 모르겠습니다.내가 아는 한, 마이크로소프트 변형은 성능이 약간 더 나쁘고 나중에 만들어졌습니다.
자세한 내용은 https://en.wikipedia.org/wiki/X86_calling_conventions 를 참조하십시오.
언급URL : https://stackoverflow.com/questions/4489012/does-c-have-a-standard-abi
'programing' 카테고리의 다른 글
C에서 문자열에 있는 문자의 발생 횟수 계산 (0) | 2023.07.15 |
---|---|
Spring mvc : 기본 응답 형식을 xml에서 json으로 변경합니다. (0) | 2023.07.15 |
data.table의 행을 문자열 키 'order(-x,v)'에서 내림차순으로 정렬하면 data.table 1.9.4 이하에서 오류가 발생합니다. (0) | 2023.07.10 |
iPhone에서 날짜 문자열에서 밀리초 동안 사용하는 형식 문자열은 무엇입니까? (0) | 2023.07.10 |
SQL Server - 큰 스크립트 파일 실행 (0) | 2023.07.10 |