프로그램 실행 시 메모리 적재 과정관련하여 질문 드립니다.
안녕하세요.
현재 프로그램 실행 시 내부 동작 관련하여 공부 중인데 쉽게 정리가 되질 않습니다.
작성한 프로그램 소스를 실행시키면 전처리, 컴파일(컴파일러, 어셈블러, 링커) 과정을 거쳐
하나의 오브젝트 파일이 생성되고 이것이 즉 .exe 파일인 것 까지 알게되었습니다.
생성된 .exe 파일 실행 후의 과정에 대해서 여러 인터넷의 자료들을 뒤져서 공부했지만 좀 모호한 부분이 있어 이렇게 질문 올립니다.
- 질문 1.
어셈블러를 통해 생성된 .obj 파일에는 이미 코드 영역, 데이터 영역 배치될 정보들이 포함되어 있는 것으로 알고 있습니다. 힙, 스택은 프로그램 동작중에 실시간으로 배치되는 것으로 알고 있구요.
그렇다면 여러 오브젝트 파일들을 하나로 합치는 링커는 파일들을 합치는 과정에서 각각의 오브젝트 파일들의 동일한 영역들끼리(코드, 데이터) 모아놓고 가상메모리의 몇 번지에 집어넣을지에 대한 정보를 저장하는 링커 스크립트 파일을 만들고 하나의 오브젝트 파일로 합치는 것(실행 파일을 생성하는 것)이 맞는 것인가요??
- 질문 2.
*.exe 실행 파일을 실행하면 Loader는 링커가 생성한 링커 스크립트 파일을 읽은 후에 스크립트에 적혀있는 내용대로 가상 메모리의 코드 영역은 몇 번지, 데이터 영역은 몇 번지에 메모리를 올려놓은 후에 main 함수부터 시작하게 되는 것이 맞나요?
- 질문 3.
힙 영역과 스택 영역은 프로그램이 실행함에 따라 프로그램 내용이 진행되는 대로 실시간으로 힙, 스택 영역에는 메모리가 올려졌다 삭제됬다 하는 것이 맞는 것이죠??
아직 무언가 개념이 덜 잡혀있는 상태라 너무나 헷갈립니다.
여기까지 오기까지도 너무나 오래 걸렸네요.ㅠㅠ
바쁘신 와중에 수고스럽겠지만 상기 질문에 대한 답변 부탁드리겠습니다.
감사합니다.
1. 네 맞습니다. 하지만 가상메모리의 특정 번지가
1. 네 맞습니다. 하지만 가상메모리의 특정 번지가 고정적으로 들어가지 않을수도 있습니다. 각종 dll이 함께 사용되는 프로그램의 경우에는 각 dll이 어느 메모리에 매핑될지 모릅니다. 따라서 RVA라고 하는 상대주소로 기입되기도 하고 로더가 추후 이 RVA를 실제 주소로 재매핑하기도 합니다.
2. 절반은 맞습니다. 절반은 맞다고 한건 정확히 말하면 main함수에 시작하는게 아닙니다. main함수는 c runtime 이 실행해주는 것이고 실제로 프로그램의 entry point는 c runtime이 됩니다. c runtime에서 각종 초기화를 거치고 프로그램의 main함수를 실행합니다. 자세한 동작 방식이 궁금하면 VC를 설치하면 CRT(C RunTime) 소스가 같이 설치됩니다. 그 부분의 소스를 까보시면 main함수를 호출하는 부분이 있고, 그 이전에 여러가지 초기화를 거치는것을 알수 있습니다. 그리고 1번 답변에 말한대로 RVA 때문에 실제 가상주소는 바뀔수도 있습니다.
3. 힙이 존재하는 가상메모리 영역과 스택이 존재하는 가상메모리 주소는 프로그램이 시작되기 전에 확정되면 바뀌는 일은 없습니다. 힙은 구현에 따라서 동적으로 바뀔수도 있지만 뭐.. 그렇게 구현할 필요가 있을까 싶군요. 질문 내용이 좀 모호한데.. 답변이 됬으려나 모르겠군요. 3번은 좀더 자세히 질문해주세요.
윈도우즈의 실행파일에 대해서 공부하시는 모양인데 PE 파일 구조를 찾아보세요. 윈도우즈의 실행파일(dll포함)의 구조이며 이게 윈도우즈가 실행파일을 메모리에 올리고 실행을 시작하는 전부입니다. 그리고 로더의 동작의 전부라고 할수 있지요.
오래된 책이긴 한데 "windows 구조와 원리"라는 책의 15장 "실행파일과 로더" 챕터를 한번 찾아보세요.
도움이 될겁니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
댓글 달기