메모리 레이아웃(Memory Layout)
•
프로세스 가상 메모리(Virtual Memory)의 구성
가상 메모리 : 프로그램을 실행할 때 운영체제가 프로세스에게 사용 가능한 메모리 공간을 할당하는 공간
프로세스 메모리 구조
•
윈도우 PE 파일은 PE 헤더와 1개 이상의 섹션으로 구성
◦
섹션의 이름
◦
섹션의 크기
◦
섹션이 로드될 주소의 오프셋
◦
섹션의 속성과 권한
.text 섹션
•
실행 가능한 기계 코드가 위치하는 영역
•
이 세그먼트에는 읽기 권한과 실행 권한이 부여
•
쓰기 권한은 악의적인 코드 삽입 방지를 위해 제거
int main() { return 31337; }
C
복사
.data 섹션
•
컴파일 시점에 값이 정해진 전역 변수들이 위치
•
CPU가 이 섹션의 데이터를 사용해야 하므로, 읽기/쓰기 권한이 부여
int data_num = 31337;
char data_rwstr[] = "writable_data"; // data
int main() { ... }
C
복사
.rdata 섹션
•
컴파일 시점에 값이 정해진 전역 상수와 참조할 DLL 및 외부 함수들의 정보가 저장
•
CPU가 이 섹션의 데이터를 읽을수 있어야 하므로, 읽기 권한이 부여되지만, 쓰기는 불가능
•
str_ptr은 전역 변수로서 .data에 위치하지만, “readonly”는 상수 문자열로 취급되어 .rdata에 위치
const char data_rostr[] = "readonly_data";
char *str_ptr = "readonly"; // str_ptr은 .data, 문자열은 .rdata
int main() { ... }
C
복사
스택
•
스택 메모리의 역할
1.
함수 내의 로컬 변수 임시 저장
2.
함수 호출 시 파라미터 전달
3.
복귀 주소 저장
•
“스택은 아래로 자란다” : 스택이 확장될 때, 기존 주소보다 낮은 주소로 확장
•
읽기/쓰기 권한이 부여
•
지역변수 choice가 스택에 저장
void func() {
int choice = 0;
scanf("%d", &choice);
if (choice)
call_true();
else
call_false();
return 0;
}
C
복사
힙
•
프로그램이 여러 용도로 사용하기 위해 할당받는 공간
•
모든 종류의 데이터 저장 가능
•
스택과의 차이점
◦
비교적 스택보다 큰 데이터도 저장 가능
◦
전역적으로 접근이 가능하도록 설계
◦
실행중 동적으로 할당받음
•
heap_data_ptr에 malloc()으로 동적 할당한 영역의 주소를 대입하고, 이 영역에 값을 쓴다. heap_data_ptr은 지역변수이므로 스택에 위치하며, malloc으로 할당받은 힙 세그먼트의 주소를 가리킨다.
int main() {
int *heap_data_ptr =
malloc(sizeof(*heap_data_ptr)); // 동적 할당한 힙 영역의 주소를 가리킴
*heap_data_ptr = 31337; // 힙 영역에 값을 씀
printf("%d\n", *heap_data_ptr); // 힙 영역의 값을 사용함
return 0;
}
C
복사
섹션 | 역할 | 일반적인 권한 | 사용 예 |
.text | 실행 가능한 코드가 저장된 영역 | 읽기, 실행 | main() 등의 함수 코드 |
.data | 초기화된 전역 변수가 위치하는 영역 | 읽기와 쓰기 | 초기화된 전역 변수, 전역 상수 |
.rdata | 초기화된 전역 상수나 임포트 데이터가 위치하는 영역 | 읽기 전용 | 전역 상수, 임포트 데이터 |
스택 | 일시적으로 저장하고 사용하는 임시 영역 | 읽기, 쓰기 | 지역 변수, 함수의 인자 등 |
힙 | 자유롭게 사용할 수 있는 영역 | 읽기, 쓰기 | malloc(), calloc() 등으로 할당 받은 메모리 |