소스 코드가 명령어로 어떻게 변할까?
3-1. 소스 코드와 명령어
모든 소스 코드는 컴퓨터가 이해 가능한 명령어로 변환된다.
고급 언어와 저급 언어
고급 언어: 인간이 이해할 수 있음
저급 언어: 컴퓨터가 직접 이해 가능함
기계어: 0과 1로 이루어진 언어
어셈블리어: 기계어를 읽기 편한 형태로 변환한 저급 언어.
한 줄 한 줄이 명령어 단위이다.
로우 레벨 개발자(임베디드 등)의 경우 위 어셈블리어를 직접 작성해야 하는 경우도 있다.
컴파일 언어와 인터프리트 언어
컴파일 언어: 소스 코드가 컴파일이라는 과정을 거쳐 저급 언어로 변환되는 언어
컴파일 결과로 나온 저급 언어는 목적 코드이다.
위 과정은 굉장히 단순화된 과정이며,
C의 경우 전처리기를 거치고, 실행 파일이 생성되는 경우 등 컴파일 언어마다 세부 추가 과정이 붙는다.
컴파일 언어 사용자라면 꼭 공부해야 한다!
인터프리트 언어: 인터프리터에 의해 한 줄씩 실행되는 언어
소스 코드 전체를 변환할 필요가 없이 실행되므로 기다릴 필요가 없다.
한 번에 번역하냐? 한 줄씩 알려주냐?
실제 변환 결과를 볼 수 있다.
같은 소스코드에 대해서도, 컴파일러에 따라 / CPU 종류에 따라 다른 어셈블리어가 만들어진다.
파이썬, 자바와 같은 인터프리터 계열은 바이트코드라 하는 중간 과정을 거친다.
주의: 컴파일 언어와 인터프리트 언어는 양분되는, 상호배척되는 관계가 아니다.
정리: 고급 언어(컴파일 언어 / 인터프리트 언어), 저급 언어(기계어 / 어셈블리어)
3-2. 명령어의 구조
소스 코드가 저급 언어로 바뀌었다. 이제 그 저급 언어의 생김새를 알아보자.
명령어는 연산의 종류와 연산에 사용할 데이터(혹은 위치)를 갖고 있다.
연산 코드: 명령어가 수행할 연산
오퍼랜드: 연산에 사용할 데이터 혹은 데이터가 저장된 위치
오퍼랜드: 데이터 자체를 저장하는 경우도 있지만, 주소를 훨씬 많이 저장한다.
오퍼랜드 필드: 오퍼랜드가 위치하는 명령어 내 공간. 주소 필드라고도 부른다.
명령어에 필요한 오퍼랜드의 개수에 따라, n-주소 명령어로 부름. 0일수도, 3일수도.
연산 코드: CPU마다 다르나 크게 네 종류가 있다.
데이터 전송 / 산술, 논리 연산 / 제어 흐름 변경 / 입출력 제어.
어떠한 연산 종류들이 있는지는 한 번씩 생각해두면 좋다. ‘무엇을 할 수 있는가?’
- 데이터 전송: MOVE(데이터 이동), STORE(저장), LOAD(CPU로), PUSH, POP(스택)
- 산술, 논리 연산: 사칙연산, ++, --, 논리연산, 비교연산
- 제어 흐름 변경: GOTO, 조건, 정지, 현재 주소를 기억하고 GOTO, 기억한 주소로 RETURN
- 입출력 제어: READ, WRITE, START IO, TEST IO
주소를 많이 쓰는 이유는? 명령어 길이에 제한이 있기 때문이다.
데이터를 직접 들고 오다가 터진다.
유효 주소: 연산에 사용될 데이터가 저장된 위치. 메모리일수도, 레지스터일수도.
명령어 주소 지정 방식: 유효 주소를 찾는 방법, 데이터를 어떻게 찾아가는지.
아래는 매우 기초적인 예시이다.
- 즉시 주소 지정 방식: 직접 데이터 명시. 빠르다.
- 직접 주소 지정 방식: 오퍼랜드 필드에 (메모리의)유효 주소를 직접 적음. 유효 주소 길이에 제한이 있다.
- 간접 주소 지정 방식: 오퍼랜드 필드에 주소의 주소를 적음. 느리다(메모리를 두번 뒤진다)
- 레지스터 주소 지정 방식: 데이터가 저장된 레지스터 명시. 메모리보단 레지스터에 접근하는게 훨씬 빠르다. CPU는 CPU 안에서만 확인하는게 빠르다.
- 레지스터 간접 주소 지정 방식: 레지스터 안에 유효 주소를 적고, 필드에는 레지스터를 적는다.
정리: 명령어(연산 코드 + 오퍼랜드), 연산 코드, 오퍼랜드(데이터 혹은 주소), 주소 지정 방식(데이터를 찾아가는 방법)
3-3. C언어의 컴파일 과정 예시
전처리기, 컴파일러, 어셈블러, 링커를 거쳐서 소스 코드가 실행 파일이 된다.
gcc 내의 특정 명령어를 통해 일부 과정까지만 일어나도록 직접 확인이 가능하다.
전처리기: 전처리 결과물을 만든다(test.i).
컴파일을 하기 위한 사전 처리 작업으로, 라이브러리 포함 / 매크로 변환 등.
컴파일러: 전처리 완료 소스 코드를 저급 언어(어셈블리어)로 변환(test.s)
어셈블러: 어셈블리어를 기계어로 변환(test.o). 목적 코드를 포함하는 목적 파일(소스 코드의 변환 목적 파일)이 된다.
링커: 각기 다른 목적 파일을 하나의 실행 파일로 묶어주는 작업(test.exe). 여러 목적 파일들을 묶어서 필요한 기능들을 연결해준다.
'개발 여행 > CS' 카테고리의 다른 글
[혼공컴+운] Chapter 2. 데이터 (0) | 2023.04.22 |
---|---|
[혼공컴운] Chapter 1. 컴퓨터 구조 시작하기 (1) | 2023.04.16 |
비전공 개발자가 추천하는 필수 컴퓨터공학 전공과목 (1) | 2023.04.16 |