Be myself :: 메모리 구조

달력

32024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

 

테스트 환경 (해당 될시에만)

 

 운영 체제 (OS) : Windows 7

 


 

상세 분석

 

프로그램을 실행 시킬때, 명령어나 여러가지 데이터들이 프로세스별로 메모리(일반적으로 RAM)에 올라가게 된다. 여기서 프로세스란 컴퓨터에서 실행되고 있는 프로그램으로 간단히 생각해도 좋다. 이 때, 32bit 시스템 기준으로 OS는 가상메모리 4G를 할당하게 된다. 그리고 각 데이터들은  편리성,보안성 등의 이유로 각 세그먼트로 나뉘어 메모리에 올라가게 된다. 이 세그먼트에는 프로그램의 명령어 코드가 있는 코드 세그먼트,초기화된 전역변수나 static변수들이 위치하는 데이터 세그먼트, 초기화 되지 않은 변수들이 위치하는 Bss 세그먼트, 동적 메모리 할당을 위한 힙 세그먼트, 지역변수 들을 위한 스택 세그먼트 등으로 나눌 수 있다. 전체적인 구조를 보고, 각 세그먼트들이 어떻게 동작하는지 살펴 보도록 하자.

 

1. 전체적인 구조 

 

 

 위의 그림에서 보이듯 메모리 영역은 일반적으로 커널영역 1~2기가, 유저영역 2~3기가 가 할당 된다. 여기서 퀴즈를 내겠다. 유저 영역은 각각 프로세스별로 할당 된다는 것은 직관적으로 알 수 있다. 커널영역도 각 프로세스별로 독립적으로 할당 되겠는가? 답은 커널영역은 프로세스가 공유하며 같이 사용한다. 지금부터 각 영역이 어떤영역인지 설명을 하겠다.

 

2. 코드영역(code segment)

 

여기는 instruct code가 위치하게 되며, 읽기만 가능하고 쓰기는 불가능하다.

 

3. 초기화된 데이터영역, 초기화 되지 않은 데이터 영역,stack 영역(data segment,bss segment,stack segment)

 

말 그대로 처음 초기화된 데이터가 저장되는 영역이다. 초기화된 전역변수나 static 변수는 data segment에 저장되고 초기화 되지 않은 전역변수나 static변수는 bss segment에 위치한다. 그렇다면 지역변수는 어디에 위치할까? 지역변수들은 stack 영역에 함수의 호출과 반환의 과정에 있어서 데이터가 저장된다. 이 부분은 그림을 통해 살펴보자.

 

 

위의 코드는 전역변수 global과 지역변수 local을 3으로 초기화 하고, notdeclare변수를 초기화 하지 않은 상태로 선언한 간단한 코드이다. 이 코드가 어떻게 어셈블리로 변한되어 지는지 살펴 보겠다.

 

 

 

위의 그림은 main함수 부분을 diassemble한 것이다.  빨간색 박스로 표시된 부분을 살펴 보면, [ebp-4] 부분에 3이 저장되어 지는것을 볼 수 있다. (local변수의 위치가 왜 [ebp-4]에 있는지는 아직 설명한 적이 없다. 이에 대해선 다음에 설명 하겠다.) 하지만, 전역변수나 초기화 되지 않은  notdeclare 변수는 값이 저장되는 명령어를 찾아 볼 수가 없다. 즉 global변수와 초기화 되지 않은 변수는 특별히 코드를 통해 초기화 되는게 아니라, 이미지(윈도우 에선 exe)가 메모리로 로드되는 순간 이미 data영역과 bss영역에 값이 초기화 되어져 있다는 것, 지역변수의 경우 특정 명령어를 통하여 stack에 로드 되는 것을 뜻한다.

 

4. Heap영역

이 영역은 malloc이나 new등과 같이 프로그래머가 프로그래밍 과정에서 동적으로 메모리를 할당하는 영역이다. 

 

5. Heap영역과, stack 영역

이 두 영역을 제외한 나머지 영역을은 프로그램이 실행되기 전에 이미 결정되어 메모리에 데이터가 고정되어져 있다. 하지만 Heap영역과 stack 영역은 프로그램이 실행됨에 따라 동적으로 바뀌는 영역이기에 메모리상에 어떻게 위치되어져야 하는것이 하나의 이슈가 된다. 두 개의 영역을 어떻게 위치시켜야 메모리를 효율적으로 사용할 수 있을까? 답은 두 개의 영역을 떨어뜨려서 서로 반대 방향으로 메모리를 할당하면 된다. 무슨말인지 그림을 통해 설명 하겠다. 

 

 

위의 그림에서 보듯이 데이터가 메모리에서 동적으로 할당 될때, 서로 겹치지 않게 하기 위해 메모리상에서 위치가 서로 떨어져 있고, 데이터가 할당 될 때도 서로 반대 방향으로(stack은 높은 주소-> 낮은 주소, heap은 낮은 주소->높은 주소) 주소값이 할당 된다. 

 

6. 공유 라이브리 영역

 

공유 라이브러리는 stack영역의 중간 쯤에 위치 하는데 이는 다음 그림을 통해 확인 할 수 있다.

 

 

ldd는 공유라이브러리 의존성 등을 확인할때 쓰는 툴이다. 이 툴을 이용해 아까 작성했던 예제를 살펴보면, libc.so.6이나 /lib/ld-linux.so.2 등의 라이브러리가 스택 영역에 위치해 있는 것을 확인 할 수 있다.

 

그림은 [원본유지로 설정]

 

 

참고 URL 및 도서

그림 참조: http://www.hackerschool.org/Sub_Html/HS_University/BOF/essential/PDF_Files/13.pdf


- OOO 도서

 

'컴퓨터구조&OS > OS' 카테고리의 다른 글

5. 보호  (0) 2014.05.05
4. Task switching  (0) 2014.05.05
3. 인터럽트 처리  (0) 2014.05.05
2. Protected 모드로의 전환  (0) 2014.05.05
1.OS의 시작  (0) 2014.05.04
Posted by flack3r
|