천문 프로그래밍과 관련된 이야기를 나눌 수 있는 곳입니다.
총 게시물 144건, 최근 0 건
   
[AstroDev의 C언어 강좌]메모리 안에서는 무슨일이?
글쓴이 : 유환용 별님  (112.♡.209.34) 날짜 : 2009-06-10 (수) 04:04 조회 : 11921
 이번 강의는 메모리에 어떤 식으로 프로그램이 올라가며 메모리 종류와 각 기능을 살펴보는 시간을 갖을 것이다. 메모리 구조에 대해서 공부하신 분들은 이번 강의를 넘어가도 좋다. 이 강의는 내가 컴퓨터 프로그래밍 언어에 대해 전혀 몰랐을 때와 같은 분들을 위해 작성한 것이다.
 필자가 혼자서 인터넷에 올라온 문서들로 공부한 것임으로 내용의 정확도가 떨어질 수도 있다. 그러니 틀린 내용은 꼭! 지적해주기 바란다.

 우리가 컴퓨터 프로그램을 실행할 때 우리눈에는 보이지 않는 많은 일들이 일어나게 된다. 특히 C 강의를 진행하면서 메모리 관련 용어들이 많이 나올것이다. 처음 내가 공부를 시작했던 컴파일러 언어는 C#이다. 현재는 C부터 다시 공부를 시작하면서 쌓아온 배경지식 덕분에 C#을 혼자 공부해도 충분히 어려움이 없었지만 처음 공부할 당시만 해도 변수와 메모리 관계, 스택, 힙이란 단어는 너무 생소하며 이해라기 보다는 암기에 가까웠고 이런 상황에 인스턴스라는 개념은 다른 먼 나라, 새로운 차원의 안드로메다 개념 이야기와 같았다. 이런 메모리 이야기가 나올 때마다 무의식 적으로 그 중요도를 외면 했었다. 메모리와 프로그램은 굉장히 밀접한 관계이다. 이 강의를 모두 읽고 나서는 이 말이 당연한 말이지만 그만큼 중요함을 먼저 알리기 위해 일부로 넣었다. 그럼 이제 본격적으로 메모리에 대해서 공부를 해보자.


메모리는 어디에 있는 것일까??

우리가 컴퓨터 내부구조를 봤을 때 흔히 램이라고 일컫는 부품이 있다. 램...그렇다. 그 녀석이 메모리다. 우리는 데이터를 저장하는 메모리 종류가 크게 스택과 힙이 있다고 알고 있다. 그렇다면 램은 물리적으로 스택과 힙 영역이 나눠져 있는 것일까? (처음 공부할 땐 이게 정말 궁금했었다) 답은 '아니다'이다. 램에는 물리적으로 영역이라는 개념이 전혀 없다고 봐도 된다. 그렇다면 메모리 영역은 언제 나눠지게 되는 것일까? 이것은 프로그램이 실행 될 때 메모리 안에서 무슨 일이 일어나는지 알아보면서 같이 소개하겠다.


프로그램이 실행 될 때 메모리 안에서는 무슨일이?

프로그램은 실행 될 때 소스 코드부터 프로그램이 사용할 모든 데이터가 메모리에 올라가 동작하게 된다. 즉 메모리, 램이 없으면 프로그램이 실행 될 수 없는 것이다. 그럼 먼저 메모리가 올라가기 전에 메모리 구조에 대해서 알아보자.


[그림]메모리 구조


위 그림은 프로그램이 실행되지 않았을 때 메모리 상태를 그린 것이다. 물론 OS도 프로그램이기 때문에 메모리에 올라가지만 이 부분은 생략하였다.

 그림을 보면 스택과 힙 같은 영역은 전혀 보이지 않는다. 그림이 보여주 듯 메모리는 프로그램이 실행되지 않으면 단지 텅빈 공간과 같다. 메모리 위치는 주소로 나타내며 그림에서 통상적으로 아래쪽이 낮은 주소를 갖게 되고 높은 곳이 높은 주소를 갖게 된다. 이 주소로 우리가 원하는 데이터를 갖고 오게 된다. 주소라는 개념은 포인터를 공부할 때 중요함으로 기억해두자. 이제 프로그램을 실행하여 메모리에 어떻게 위치하는지 그리고 스택과 힙은 어떻게 생기는지 알아보자.


[그림] 세그먼트 구조


 프로세스 즉 프로그램이 실행이 되면 세그먼트 단위로 메모리에 올라가게 된다. 위 그림에서 나타내는 세그먼트는 하나의 프로그램을 나타내며 각각의 세그먼트는 서로 다른 프로그램, 프로세스를 뜻하게 된다.


세그먼트 크기는 어떻게 정해지는 것일까?

우리가 컴퓨터를 구입할 때 32비, 64비트 이야기를 들었을 것이다. 이 비트는 CPU가 한번에 연산 할 수 있는 데이터 크기를 뜻한다. 메모리 이야기를 하다가 갑자기 CPU이야기를 하는지 의아해 할 것이다. CPU 연산 크기에 따라 세그먼트 크기가 달라지기 때문이다. 즉 32bit CPU는 0 ~ 2^32 - 1 크기의 세그먼트 범위를 갖으며 64bit CPU는 0 ~ 2^64 - 1 범위를 갖을 수 있다. CPU는 세그먼트 크기와 함께 컴퓨터에 장착되는 램 용량 인식 최대 범위가 달라지게 된다. 32비트 CPU에는 최대 4GB까지만
인식이 되며 64비트는 16TB까지 인식 된다.

잠시 생각해보자 뭔가 이상하지 않은가? 32비트 CPU 환경에서는 램이 최대 4GB까지 인식 된다고 하였다. 그런데 프로그램 하나당 최대 4GB 크기의 세그먼트 크기를 제공한다고 하였다. 요즘 같은 멀티테스킹 환경 컴퓨터 안에서는 적어도 프로그램 2개 이상 실행을 한다. 그렇다면 메모리는 4GB 이상 필요하지 않을까? 그래야 프로그램이 동작하지 않을까? 이것은 우리가 흔히 알고 있는 가상메모리라는 기술로 해결한다고 한다. 그리고 모든 프로그램이 무조건 4GB 크기로 세그먼트 크기가 정해지는 건 아니다 다음 세그먼트 구조를 나눠보면 알겠지만 코드 크기와 프로세스가 사용할 총 데이터 크기를 계산하여 세그먼트 크기가 결정이 된다.

2^(비트) / 1024(1GB) = 램 인식 최대 크기

32비트 계산

2^32 / 1024 = 4



세그먼트 구조

[그림] 세그먼트 번호


 하나의 세그먼트는 다시 크게 세개 세그먼트로 나눠지게 된다.
 1번 세그먼트 - Text Segment 또는 Code Segment, 기계어 코드들이 올라오게 된다. 이 세그먼트에는
실행 코드가 올라오는 부분이기 때문에 쓰기가 금지 되어 있다. 이곳에 올라가는 기계어는 소스를 컴파일 하고 나서 만들어진 실행파일의 기계어 코드이다.
 2번 세그먼트 - Data Segment와 BSS Segment로 나눠진다. Data Segment에는 초기화 된 전역 변수,
문자열, 기타 상수가 저장되며 BSS Segment에는 초기화 되지 않은 전역 변수, 문자열,
기타 상수들이 저장되며 쓰기가 허용되지만 크기는 고정되어있다.
3번 세그먼트 - Stack Segment와 Heap Segment가 위치하게 된다. 이 세그먼트들이 바로 우리가
알고 있는 스택 메모리와 힙 메모리이다. 이것은 다음 파트에 이어서 자세히 설명하겠다.



스택 세그먼트와 힙 세그먼트

스택 세그먼트와 힙 세그먼트를 설명해주기 전에 스택과 힙에 대한 개념을 먼저 집고 넘어가겠다.

 스택을 소개할 때 흔히 FILO(First In Last Out) 또는 LIFO(Last In First Out)라고 한다. 값이 먼저 들어 간(할당된) 데이터가 나중에 나오는(호출이 되는) 메모리 구조가 바로 스택이다.
 힙은 스택과 다르게 FIFO(First In First Out) 또는 LILO(Last In Last Out)라 칭한다. 말 그대로 먼저 들어간 데이터가 가장 먼저 나오며 마지막으로 들어간 데이터가 마지막으로 나온다는 말이다.
스택과 힙에 대한 개념은 다음 강의 때 지역변수와 더불어 다시 설명하겠다.


[그림] 스택과 힙


그림에서 화살표는 각 메모리 크기가 증가하는 방향을 나타낸 것이다. 스택과 힙의 크기는 동적으로 변하며 스택과 힙은 마주보는 방향으로 증가 감소 한다. 스택이 증가하면 힙이 줄어드는 형식이다.
 힙 메모리 주소는 메모리 크기가 증가하는 방향으로 메모리 주소도 증가하게 된다. 즉 실제 메모리 주소 크기가 증가하는 방향으로 힙 메모리도 주소값이 증가하게 된다. 그러나 스택은 반대이다. 스택 메모리가 증가하는 방향으로 메모리 주소값이 증가하지만 실제 메모리 주소랑은 다르다. 스택 메모리가 증가하는 방향은 실제 메모리 주소가 낮아지는 방향이므로 스택 메모리의 높은 주소의 위치는 실제 메모리 낮은 주소가 된다. 어렵게 풀어 놓은 말은 아래 그림으로 한번에 이해가 될것이다.


[그림] 스택 메모리 주소 구조




이것으로 프로세스가 실행 될 때 메모리 구조를 살펴보았다. 이 개념들은 C 포인터에서도 중요하지만 C++, 자바, C# 그외 언어에도 중요한 내용이므로 이 강의 이외에 다른 문서들을 참고하여 확실히 학습해 놓자.


 

참고문서
Jon  Erickson, 에이콘, 해킹 공격의 예술

달고나, wowhacker, 해커 지망자들이 알아야 할 BufferOverflow Attack의 기초

[이 게시물은 최고관리자님에 의해 2012-12-20 11:00:41 프로그래밍 강좌에서 이동 됨]

지용호별님 (121.♡.140.207) 2009-06-10 (수) 11:11
좋은 내용입니다. 근데 사진이 안보이네요. ^^
댓글주소
유환용별님 (112.♡.209.34) 2009-06-10 (수) 11:11
윽 ㅜㅜ 수정했습니다. 오늘 새벽까지만 해도 잘 나왔었는데 ㅜㅜ
댓글주소
정재원별님 (121.♡.87.50) 2009-06-11 (목) 12:12
메모리 영역을 세그먼트라고 하는건가요?
댓글주소
정재원별님 (210.♡.147.232) 2009-06-11 (목) 13:13
세그먼트(Segment)는 사전적의미로 "부분"이라는 뜻입니다. 옵셋(Offset)은 "차감계산을 하다"라는 뜻이죠? 세그먼트는 메모리의 한 부분이고요. 옵셋은 그 세그먼트 내의 상대적 주소를 말합니다. 기준이 되는 세그먼트 주소값에서 얼마나 떨어져 있는지를 나타내는 값입니다.
댓글주소
정재원별님 (210.♡.147.232) 2009-06-11 (목) 13:13
메모리 관련 segment라는 개념은 16bit address line(64 K byte)으로
20 bit (64K x 16 = 1M byte) 공간을 악세스 하기 위해
INTEL의 8086 cpu에서 사용된 개념입니다.
현재의 펜티엄급의 32bit 이상의 cpu에, windows환경에서는 그닥 ....
댓글주소
유환용별님 (112.♡.209.34) 2009-06-11 (목) 13:13
맞습니다. 제가 봤던 문서는 8086 시스템을 기준으로 서술 되어 있었습니다. 하지만 메모리 구조를 이해하기에는 무리가 없었습니다. 옵셋이라는 개념도 소개를 안드린 이유가 아직 이르다고 생각하였고 이 글의 목적은 프로그램이 실행할 시에 메모리 안에 어떤일이 일어나는지 앞으로 나올 스택과 힙이라는 메모리는 어디에 어떻게 생성되는지 알려드리기 위함입니다.

메모리에 올라간 하나의 프로그램 한 영역으로서 세그먼트라고 저도 사용하였고 세그먼트 보다 적절한 단어가 떠오르지가 않아서 메모리에 올라간 프로그램 부분을 세그먼트라고 부른 것인데 용어 때문에 그러시다면 더욱 적절한 용어를 소개해주시기 바랍니다.

물론 제가 혼자서 공부하였기 때문에 제가 세그먼트라는 뜻 자체를 잘못 이해했을수도 있지만 인텔 cpu 시스템에서는 말씀하신 것 처럼 그런 개념을 가졌고 중요하였고 요즘 메모리의 양은 옛날에 비해서 방대해졌기에 그 의미의 중요도가 줄어들었을 뿐 개념은 변함 없다고 생각합니다.
댓글주소
유환용별님 (112.♡.209.34) 2009-06-11 (목) 14:14
참고로 세그먼트에 대한 단어 정의 입니다.
http://enc.daum.net/dic100/contents.do?query1=15XXXX8786
댓글주소
조우성별님 (211.♡.29.176) 2009-06-12 (금) 00:00
멋진데!
댓글주소
정재원별님 (210.♡.147.192) 2009-06-12 (금) 12:12
세그먼트란 용어를 처음 들어 봐서 조사좀 해봤어 ㅋ
댓글주소
유환용별님 (112.♡.209.34) 2009-06-12 (금) 12:12
제 강좌에 유일하게 관심 댓글을 남겨주시는 형님 ㅜㅜ
댓글주소
   

총 게시물 144건, 최근 0 건
번호 제목 글쓴이 날짜 조회 추천
144  음양력 변환 프로그램 CalTime 3.4 +1 김동빈별님 11-24 7092 0
143  현재 시간에 따른 태양, 달 위치 계산. +1 조재훈별님 08-30 6341 0
142  [DreamSpark] Microsoft의 정품 프로그램을 무료로 … +6 백승우별님 01-21 8225 0
141  일식 예측을 위한 태양과 달의 위치 계산 +1 이형철별님 11-21 10750 0
140  사이토구니치의 古天文學 번역판을 공개하며 +1 이형철별님 08-22 11152 2
139  [AstroDev의 C언어 강좌] 나왔다 Hello World!!! +3 유환용별님 07-01 8575 0
138  [AstroDev의 C언어 강좌] 컴퓨터 데이터 표현 방… 유환용별님 06-28 9845 0
137  IAU2000 장동 모델 +2 김창환별님 06-25 11767 0
136  [AstroDev의 C언어 강좌]메모리 안에서는 무슨일… +10 유환용별님 06-10 11922 0
135  [AstroDev의 C언어 강좌]우리는 무엇을 준비해야… +7 유환용별님 06-08 9817 0
134  [AstroDev의 C언어 강좌]우리는 무엇을 준비해야… +3 유환용별님 06-07 9393 0
133  [AstroDev의 C언어 강좌]C언어를 공부하기 전에 … +4 유환용별님 06-06 9982 0
132  IAU2006 세차 모델 +1 김창환별님 05-18 10560 0
131  각도변환문제 : 도(degree), 시(hour), 라디안(radia 지용호별님 04-15 17931 0
130  지구의 세차운동(歲差運動, Precession) 계산하… +5 지용호별님 04-14 14418 0
 1  2  3  4  5  6  7  8  9  10  맨끝
 
Since 2001.2.7 미래창조과학부 등록 비영리민간단체 천문노트. Copyright All rights reserved.
단체명 : 천문노트  |    고유번호 : 101-82-15888  |    대표자명 : 김태욱, 조우성  |    주소 : 138-804 서울특별시 송파구 가락동 93 금강빌딩 7층 710호  |    전화 : 02-543-3295  |    Fax : 02-6918-6888  |    통신판매신고번호 : 종로 제01-5696호  |    개인정보관리책임자 및 사이트관리자 : 지용호