본문 바로가기

Embedded Programming/컴구조&운영체제

프로세스의 메모리 영역

32비트 시스템에서 프로세스(실행 중인 프로그램) 생성시 4GB의 메모리를 할당받을 수 있는데,

이는 램만으로는 충당하기엔 턱없이 부족하다.

그래서 운영체제는 램과 하드디스크를 하나로 묶어 가상 메모리로 관리한다.

대부분의 시스템에서는 주로 페이징(Paging)이라는 기법으로 가상 메모리를 관리한다.

페이징 기법은 아직 모르므로-_-; 가상메모리의 영역에 대해서만 이야기해보자.


가상 메모리는 프로세스당 아래와 같은 구조를 가지는데,

모두 5대영역으로 나뉜다. 아래 그림과 같이 데이터를 분류하여 각 영역에 저장하는 것이다.



위의 메모리 영역은 크게 두가지로 나눌 수 있는데 컴파일시 크기가 고정되는 code, data, bss 영역과 실행시 메모리가 할당되었다 반납되는 heap, stack영역으로 나눌 수 있다.


① 메모리 할당이 고정되는 영역

* 코드 영역 - 코드영역은 실행 파일을 구성하는 명령어들이 올라가는 메모리 영역으로 함수, 제어문, 상수 등이 여기에 지정된다.

* 데이터 영역 & BSS- 데이터 영역은 BSS와 함께 묶어서 데이터 영역으로 칭하기도 하는데 이는 전역변수와 Static변수가 지정되는 영역이다. 초기화 되지 않은 전역변수들은 BSS에 지정된다.


② 실행 중에 메모리를 할당하는 영역(할당과 반납이 이루어짐)

* HEAP 영역 - HEAP 영역은 malloc(), calloc() 등으로 프로그래머가 자율적으로 메모리 크기를 할당할 수 있는 영역이다. 위의 함수들은 free()함수로 할당된 영역을 반납해줘야하므로 동적할당 영역에 속한다. 

* STACK 영역 - STACK 영역은 지역변수가 할당되는 영역으로 함수가 호출되면 할당되었다 함수의 종료시 반납되는 영역이다. 

위의 HEAP과 STACK영역은 사실 같은 공간을 공유한다. HEAP이 메모리 위쪽 주소부터 할당되면 STACK은 아래쪽 부터 할당되는 식이다. 그래서 각 영역이 상대 공간을 침범하는 일이 발생할 수 있는데 이를 각각 HEAP OVERFLOW, STACK OVERFLOW라고 칭한다.




이번 포스트에서는 함수와 변수가 메모리에 저장되는 주소로

메모리 영역이 나뉘어 있다는 것을 확인해보자.


// 함수와 변수의 메모리 영역
#include <stdio.h>

int main()
{
  int a = 1;
  int b = 2;
  int c = 3;
  int d = 4;
  int e = 5;

  // 변수의 주소 : 0012FF~
  printf("%08X %08X %08X %08X %08X\n"
        &a, &b, &c, &d, &e);

  // 함수의 주소 : 004010~
  printf("main()의 주소 : %08X\n", main);
  printf("printf()의 주소 : %08X\n", printf);
  return 0;
}

<실행화면>


위의 예제에서 확인할 수 있듯이 변수의 메모리 주소와

함수의 메모리 주소는 0012FF~ 004010~으로 많~이 떨어져 있는 것을 확인 할 수 있다.-_-;