많은 플랫폼에서 각 모듈 내의 모든 전역 또는 정적 할당은 컴파일러에 의해 3 개 이하의 통합 할당 (초기화되지 않은 데이터 (보통 "bss"라고도 함), 초기화 된 쓰기 가능한 데이터 (보통 "데이터"라고 함))으로 통합됩니다. ), 상수 데이터에 대한 하나 ( "const"), 프로그램 내에서 각 유형의 모든 전역 또는 정적 할당은 링커에 의해 각 유형에 대해 하나의 전역으로 통합됩니다. 예를 들어, int
4 바이트 라고 가정하면 모듈은 정적 할당으로 다음을 갖습니다.
int a;
const int b[6] = {1,2,3,4,5,6};
char c[200];
const int d = 23;
int e[4] = {1,2,3,4};
int f;
링커는 bss의 경우 208 바이트, "data"의 경우 16 바이트, "const"의 경우 28 바이트가 필요하다는 것을 링커에게 알려줍니다. 또한 변수에 대한 모든 참조는 영역 선택기 및 오프셋으로 대체되므로 a, b, c, d 및 e는 bss + 0, const + 0, bss + 4, const + 24, data로 대체됩니다. +0 또는 bss + 204
프로그램이 연결되면 모든 모듈의 모든 bss 영역이 함께 연결됩니다. 마찬가지로 데이터 및 const 영역. 각 모듈에 대해 bss 관련 변수의 주소는 모든 이전 모듈의 bss 영역의 크기만큼 증가합니다 (데이터 및 const와 마찬가지로). 따라서 링커가 완료되면 모든 프로그램에 하나의 bss 할당, 하나의 데이터 할당 및 하나의 const 할당이 있습니다.
프로그램이로드되면 일반적으로 플랫폼에 따라 다음 4 가지 중 하나가 발생합니다.
실행 파일은 각 종류의 데이터 및 초기화 된 데이터 영역에 필요한 초기 바이트 수를 나타내는 바이트 수를 나타냅니다. 또한 bss, data 또는 constative 상대 주소를 사용하는 모든 명령어 목록이 포함됩니다. 운영 체제 또는 로더는 각 영역에 적절한 공간을 할당 한 다음 해당 영역의 시작 주소를 필요한 각 명령에 추가합니다.
운영 체제는 세 종류의 데이터를 모두 보유하기 위해 메모리 청크를 할당하고 애플리케이션에 해당 메모리 청크에 대한 포인터를 제공합니다. 정적 또는 전역 데이터를 사용하는 모든 코드는 해당 포인터를 기준으로이를 역 참조합니다 (대부분의 경우 포인터는 응용 프로그램 수명 동안 레지스터에 저장 됨).
운영 체제는 이진 코드를 보유하고있는 것을 제외하고는 처음에는 메모리를 응용 프로그램에 할당하지 않지만 응용 프로그램은 운영 체제에 적절한 할당을 요청해야합니다.
운영 체제는 처음에 응용 프로그램을위한 공간을 할당하지 않지만 시작시 응용 프로그램에 적절한 할당을 요청합니다 (위와 같이). 이 응용 프로그램에는 메모리가 할당 된 위치를 반영하기 위해 업데이트해야하는 주소 목록이 포함 된 명령어 목록이 포함되지만 (첫 번째 스타일과 같이) OS 로더가 응용 프로그램을 패치하는 대신 응용 프로그램 자체에 패치를 적용 할 수있는 충분한 코드가 포함됩니다 .
네 가지 방법 모두 장단점이 있습니다. 그러나 모든 경우에 컴파일러는 임의의 수의 정적 변수를 고정 된 적은 수의 메모리 요청으로 통합하고 링커는 모든 변수를 적은 수의 통합 할당으로 통합합니다. 응용 프로그램이 운영 체제 나 로더에서 메모리 청크를 받아야하지만, 큰 청크에서 개별 조각을 필요한 모든 개별 변수에 할당하는 것은 컴파일러와 링커입니다.