3-1. 소스 코드와 명령어
시작하기 전에
모든 소스 코드는 컴퓨터 내부에서 명령어로 변환된다.
고급 언어와 저급 언어
개발자는 프로그래밍 언어로 프로그램을 만들지만, 컴퓨터는 그렇게 만들어진 프로그램을 실행해 주지만, 컴퓨터는 프로그래밍 언어를 이해할 수 없다
고급 언어
사람을 위한 언어를 일컫는 말로, 대부분의 프로그래밍 언어가 고급 언어에 속한다
저급 언어 (명령어)
컴퓨터가 직접 이해하고 실행할 수 있는 언어를 일컫는 말로, 컴퓨터가 이해, 실행할 수 있는 언어다
따라서, 고급 언어로 작성된 소스 코드가 실행되려면 반드시 저급 언어, 즉 명령어로 변환되어야 한다
- 기계어 : 0과 1의 명령어 비트로 이루어진 언어 = 0과 1로 이루어진 명령어 모음
- 어셈블리어 : 0과 1로 표현된 명령어(기계어)를 읽기 편한 형태로 번역한 언어
- 어셈블리어를 읽으면 컴퓨터가 프로그램을 어떤 과정으로 실행하는지, 즉 프로그램이 어떤 절차로 작동하는지를 가장 근본적인 단계에서부터 하나하나 추적하고 관찰할 수 있기 때문
컴파일 언어와 인터프리터 언어
고급 언어는 어떻게 저급 언어로 변환될까?
- 컴파일 방식 (컴파일 언어)
- 인터프리트 방식 (인터프리터 언어)
컴파일 언어
컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 고급 언어
- 컴파일 : 컴파일 언어로 작성된 소스 코드는 코드 전체가 저급 언어로 변환되는 과정
- 컴파일이 성공적으로 수행되면 개발자가 작성한 소스 코드는 컴퓨터가 이해할 수 있는 저급 언어로 변환 → 목적 코드 : 컴파일러를 통해 저급 언어로 변환된 코드
- 컴파일러 : 컴파일을 수행해 주는 도구
- 개발자가 작성한 소스 코드 전체를 쭉 훑어보며 소스 코드를 처음부터 끝까지 저급 언어로 컴파일한다
인터프리터 언어
인터프리터에 의해 소스 코드가 한 줄씩 실행되는 고급 언어
소스 코드 전체가 저급 언어로 변환되는 컴파일 언어와는 달리, 인터프리터 언어는 소스 코드를 한 줄씩 차례로 실행
- 인터프리터 : 소스 코드를 한 줄씩 저급 언어로 변환하여 실행해 주는 도구 (변환 시간이 필요 없음)
마무리
6가지 키워드로 정리하는 핵심 포인트
- 고급 언어는 사람이 이해하고 작성하기 쉽게 만들어진 언어
- 저급 언어는 컴퓨터가 직접 이해하고 실행할 수 있는 언어
- 저급 언어는 0과 1로 이루어진 명령어로 구성된 기계어와 기계어를 사람이 읽기 편한 형태로 번역한 어셈블리어가 있음
- 컴파일 언어는 컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 언어
- 인터프리터 언어는 인터프리터에 의해 소스 코드가 한 줄씩 저급 언어로 변환되어 실행되는 언어
3-2. 명령어의 구조
시작하기 전에
여러 가지 명령어를 보면서 개념을 학습해보자
연산 코드와 오퍼랜드
명령어는 ‘무엇을 대상으로, 어떤 작동을 수행하라’는 구조로 되어 있다
- 명령어는 연산 코드와 오퍼랜드로 구성되어 있다
- 연산 코드(연산자) : 명령어가 수행할 연산
- 연산 코드가 담기는 영역을 연산 코드 필드라 한다
- 오퍼랜드(피연산자) : 연산에 사용할 데이터, 연산에 사용할 데이터가 저장된 위치
- 오퍼랜드가 담기는 영역을 오퍼랜드 필드라고 한다
- 연산 코드(연산자) : 명령어가 수행할 연산
기계어와 어셈블리어 또한 명령어이기 때문에 연산 코드가 오퍼랜드로 구성되어 있다
오퍼랜드
‘연산에 사용할 데이터’ 또는 ‘연산에 사용할 데이터가 저장된 위치’를 의미한다
따라서, 오퍼랜드 필드에는 숫자와 문자 등을 나타내는 데이터 또는 메모리나 레지스터 주소가 올 수 있다
오퍼랜드는 명령어 안에 하나도 없을 수도 있고, 한 개만 있을 수도 있고, 두 개 또는 세 개 등 여러 개가 있을 수 있다
0-주소 명령어: 오퍼랜드가 하나도 없는 명령어1-주소 명령어: 오퍼랜드가 하나인 명령어n-주소 명령어: n 개인 명령어
연산 코드
명령어가 수행할 연산을 의미한다
- 데이터 전송
- 산술/논리 연산
- 제어 흐름 변경
- 입출력 제어
주소 지정 방식
오퍼랜드 필드에 데이터가 저장된 위치를 명시할 때 연산에 사용할 데이터 위치를 찾는 방법
명령어의 길이 때문에 메모리 안에 데이터를 저장하고, 오퍼랜드 필드 안에 해당 메모리 주소를 명시한다면 표현할 수 있는 정보의 가짓수가 늘어난다
- 유효 주소 : 연산의 대상이 되는 데이터가 저장된 위치
즉시 주소 지정 방식
연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시하는 방식
- 표현할 수 있는 데이터의 크기가 작아지는 단점
- 연산에 사용할 데이터를 메모리나 레지스터로부터 찾는 과정이 없기 때문에 빠름
직접 주소 지정 방식
오퍼랜드 필드에 유효 주소를 직접적으로 명시하는 방식
- 오퍼랜드 필드에서 표현할 수 있는 데이터의 크기는 커지지만, 표현 범위가 연산 코드의 비트 수만큼 줄어듦
- 따라서, 표현할 수 있는 오퍼랜드 필드의 길이가 연산 코드의 길이만큼 짧아져 표현할 수 있는 유효 주소에 제한이 생길 수 있음
간접 주소 지정 방식
유효 주소의 주소를 오퍼랜드 필드에 명시하는 방식
- 직접 주소 지정 방식보다 표현은 많이 할 수 있지만 일반적으로 아주 느리다
레지스터 주소 지정 방식
직접 주소 지정 방식과 비슷하게 연산에 사용할 데이터를 저장한 레지스터를 오퍼랜드 필드에 직접 명시하는 방식
- 일반적으로 CPU 외부에 있는 메모리에 접근하는 것보다 CPU 내부에 있는 레지스터에 접근하는 게 빠름
- 표현할 수 있는 레지스터 크기에 제한이 생김
레지스터 간접 주소 지정 방식
연산에 사용할 데이터를 메모리에 저장하고 그 주소 (유효 주소)를 저장한 레지스터를 오퍼랜드 필드에 명시하는 방식
- 간접 주소 지정 방식보다 빠르고, 메모리에 접근하는 횟수가 한 번으로 줄어듦
| 즉시 주소 지정 방식 | 연산에 사용할 데이터 |
|---|---|
| 직접 주소 지정 방식 | 유효 주소 (메모리 주소) |
| 간접 주소 지정 방식 | 유효 주소의 주소 |
| 레지스터 주소 지정 방식 | 유효 주소 (레지스터 이름) |
| 레지스터 간접 주소 지정 방식 | 유효 주소를 저장한 레지스터 |
마무리
4가지 키워드로 정리하는 핵심 포인트
- 명령어는 연산 코드와 오퍼랜드로 구성됨
- 연산 코드는 명령어가 수행할 연산을 의미
- 오퍼랜드는 연산에 사용할 데이터 또는 연산에 사용할 데이터가 저장된 위치를 의미
- 주소 지정 방식은 연산에 사용할 데이터 위치를 찾는 방법