일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- vue2
- js
- realIndex
- querySelector
- css
- loop:true
- centerSlides
- slidePerGroup
- jquery
- archiver
- slideChange
- JavaScript
- swiper
- index
- prettier
- swiperOption
- javascirpt
- error
- slidePerView
- classlist
- vscode
- activeIndex
- eslint prettier
- display
- CORS
- 인덱스
- watchOverflow
- Vue
- v-bind
- eslint
- Today
- Total
코딩하는 둥둥
[ 쉽게 배우는 운영체제 ] 7-5. 컴파일과 메모리 관리 본문
컴파일 과정
C언어나 자바로 작성한 소스코드는 컴파일 과정을 거쳐 목적 코드가 된다.
컴파일러는 고급언어로 작성된 소스코드를 기계어로 번역하면서 여러 가지 작업을 수행한다.
오류가 있는지 점검하고 최적화를 통해 필요 없는 변수와 코드를 삭제해서 만들어진 기계어 코드를 목적 코드라고 한다.
목적 코드는 기계어 코드로 가기 직전의 초벌 번역 상태이다.
경우에 따라서는 하나의 응용 프로그램을 여러 프로그래머가 나누어 작업하기도 하는데, 여러 프로그래머가 작성한 소스코드를 합쳐서 컴파일할 때 문제가 발생할 수도 있다.
이때 각자 오류를 수정해 다시 합친 후 컴파일하는 것은 번거롭기 때문에 자신의 코드를 만든 후 목적 코드만 따로 모아서 컴파일한다. 이를 분할 컴파일이라고 한다.
목적 코드가 만들어졌다는 것은 소스코드의 오류 검증과 코드 최적화가 이루어졌다는 뜻으로, 분할 컴파일을 하면 공동으로 사용하는 코드나 변수만 정리하면 되기 때문에 분할 작업이 쉬워진다.
목적 코드를 만든 후 연결 단계에서는 목적 코드에 라이브러리 코드를 삽입해 최종 파일을 만든다.
라이브러리
미리 만들어진 함수들을 모아놓은 파일.
대표적인 라이브러리로는 입출력 관련 함수들을 모아놓은 <studio.h>가 있다.
소스코드에 printf() 문을 사용하면 연결 단계에서 printf문에 해당하는 기계어 코드를 <studio.h> 라이브러리에 가져와 목적 코드에 삽입한다.
프로그래머는 소스코드 맨 앞에 #include <studio.h>라고 명시만 하면 된다.
<math.h> 라이브러리는 수학 관련 함수를 모아놓은 라이브러리로 소스코드 맨 앞에 #include <math.h>라고 명시한다.
사인, 코사인, 탄젠트 등의 수학 함수들을 사용할 수 있다.
변수와 메모리 할당
컴파일과 메모리 사이에는 밀접한 연관관계가 있다.
컴파일 과정에서 가장 중요한 것은 메모리를 확보하고 정리하는 부분이다.
1
2
3
|
char str = 'a'; // 변수 str을 문자형으로 선언후 그곳에 a를 넣어라
int vol = 7; // 변수 vol을 정수형으로 선언후 그곳에 7를 넣어라
float pri = 2.3; // 변수 pri을 실수형으로 선언후 그곳에 2.3를 넣어라
|
cs |
기계어는 메모리 주소를 사용한다.
따라서 char str='a'는 기계어에서 메모리 주소 0번지에 a를 넣으라는 명령으로 번역되어 컴파일러 0번지에 a를 넣고 이곳을 문자형이 들어가는 공간으로 기억한다.
int vol=7은 메모리의 1번지부터 4번지까지 확보한 후 그곳에 정수 7을 넣고, float pri=2.3도 메모리의 5번지부터 12번지까지 확보한 후 그곳에 실수 2.3을 넣는다.
여기서는 설명을 위해서 문자 a, 정수 7, 실수 2.3으로 작성했지만 실제로는 2진수로 저장된다.
위의 사례에서 char, int, float는 보관하려는 자료의 형태를 나타낼 뿐만 아니라 사용하려는 메모리의 크기를 나타내기도 한다. (char은 1Byte, int는 4Byte, float는 8Byte를 사용)
자료형과 자료형에 따라 할당되는 메모리 크기에 대한 자세한 내용은 다음과 같다.

따라서 컴파일러는 지정한 자료형의 크기에 따라 메모리를 확보하고 그곳에 적당한 값을 집어넣으며, 모든 변수에 대해 메모리를 확보하고 오류를 찾기 위해 심벌 테이블을 유지한다.
심벌 테이블에서 보듯이 각 변수는 이름, 종류, 범위, 주소를 가진다.
범위는 각 변수를 사용할 수 있는 영역을 나타내며 이러한 영역을 범위(Scope)라고 한다.
컴파일러는 변수를 사용할 때마다 사용범위를 넘는지 확인한다.
심벌 테이블에서 변수의 주소는 있는데 크기가 없는 이유는 변수의 종류마다 크기가 정해져 있기 때문에 시작 주소만 명시하면 그 크기는 자동으로 정해지기 때문이다.
변수는 메모리 주소의 또 다른 이름으로, 기계어 입장에서는 변수를 알 필요가 없고 메모리 주소만 필요로 한다.
하지만 프로그래머는 메모리 주소 값만으로는 기억하기 어렵기 때문에 각 주소에 대응하는 변수를 사용한다.
프로그래머가 변수를 사용해 프로그램을 만들면 컴파일러는 모든 변수를 메모리 주소로 바꿔 기계어로 된 실행파일을 만든다.
결론적으로 컴파일러는 프로그래머가 만든 변수를 적당한 크기의 메모리 주소로 변환하여 기계어로 바꾼다.
주의할 점은 컴파일러로 만들어진 주소는 상대 주소로, 앞의 char str='a';는 0번지에 만들어진다고 했지만 주소 0번지에는 운영체제가 자리하고 있다.
사용자의 주소 0번지는 실제 메모리의 주소로 변환되며 이는 메모리 관리자가 담당하기 때문에 프로그래머는 주소가 항상 0번지부터 시작한다고 가정하고 프로그래밍하면 된다.
'Computer Science > 쉽게 배우는 운영체제' 카테고리의 다른 글
[ 쉽게 배우는 운영체제 ] 8-1. 가상 메모리의 개요 (0) | 2022.09.09 |
---|---|
[ 쉽게 배우는 운영체제 ] 7-4. 다중 프로그래밍 환경에서의 메모리 할당 (0) | 2022.08.30 |
[ 쉽게 배우는 운영체제 ] 7-3. 단일 프로그래밍 환경에서의 메모리 할당 (0) | 2022.08.26 |
[ 쉽게 배우는 운영체제 ] 7-2. 메모리 주소 (0) | 2022.08.23 |
[ 쉽게 배우는 운영체제 ] 7-1. 메모리 관리의 개요 (0) | 2022.08.21 |