각 프로그램은 다음과 같은 여러 세그먼트로 구분됩니다.
- 코드 세그먼트
- 데이터 세그먼트
- 스택 세그먼트
- 힙 세그먼트
그러나 그 진행에 대한 책임자는 누구입니까? 컴파일러와 링커는 이러한 세그먼트에 대한 대화를 지원해야합니다.
- 컴파일러와 링커 개발자에 의해 처음으로 구현 되었습니까? 초기 운영 체제에서 사용 했습니까?
또는
- 운영체제 개발자가 먼저 구현했기 때문에 컴파일러와 링커 개발자는 조정이 필요 했습니까?
답변
이는 부분적으로 CPU 설계에 기반을두고 있습니다.
1980 년대에 들어서면서 대부분의 컴퓨터는 16 비트 아키텍처를 가졌지 만,
그래서 포인터는 가상 주소 공간에 접근 할 수있다.
2의 16 (65536) 바이트입니다.
이것은 자연스럽게 너무 제한적이라고 간주되었습니다.
코드 세그먼트가 다른 세그먼트와 분리되면,
너는 2을 가질 수있다. 16 바이트 상당의 코드 (지침)
및 2 16 데이터의 바이트 가치는 나 빠지지 않습니다.
프로그램 / 프로세스의 “데이터 공간”
(가능한 가장 넓은 의미의 용어 사용)에는 다음을 포함 할 수 있습니다
- 다음을 포함한 초기화 된 데이터
- 문자열 (예 :
printf("Hello, world\n");
), - 초기화 된 변수 (예 :
int i = 42;
), - 경우에 따라 코드에 사용 된 상수 (예 :
y = x + 17;
),
- 문자열 (예 :
- 초기화되지 않은 변수
(예컨대,int j;
,char mydata[80];
정적 / 전역 컨텍스트에서) - 동적으로 할당 된 메모리 (
malloc
,new
), - 스택 (함수 인수, 저장 / 복원 정보 및 로컬 변수).
나는 뭔가를 남기고 있을지 모르지만 레지스터는 실제로 셀 수 없다.
(그들은 본질적으로 초기화되지 않은 변수의 특별한 경우이다)
공유 메모리는이 논의의 범위를 벗어납니다.
위의 내용 중에서,
초기화 된 데이터 만 실행 파일에 저장해야합니다.
초기화되지 않은 변수에 대한 공간 및
스택은 프로그램이 실행될 때 OS에 의해 자동으로 할당됩니다.
그래서 컴파일러는 초기화 된 데이터를 추적해야했습니다.
및 초기화되지 않은 변수를 별도로 지정해야합니다.
또 하나의 주름은 Intel 8086 CPU
(펜티엄의 위대한 증조부)
각 세그먼트는 하나의 크고 연속적인 메모리 블록이되어야했습니다.
Unix 커널은 하나의 큰 코드 블록과 하나의 큰 데이터 블록으로 구성됩니다
(초기화 된 데이터 및 초기화되지 않은 변수)
각 프로세스마다 별도의 스택을 사용합니다.
따라서 8086은 능력이 필요했습니다.
스택을 다른 모든 데이터와 다른 세그먼트에 포함시킵니다.
이 웹에 관한 많은 정보가 있습니다.
예를 들어, Wikipedia :