3-1 소스 코드와 명령어
- 모든 소스 코드는 컴퓨터 내부에서 명령어로 변환된다.
- 프로그래밍 언어가 어떻게 명령어가 되어 실행되는지 알아보자!
고급 언어와 저급 언어
- 고급 언어는 ‘사람을 위한 언어’다.
- 컴퓨터는 프로그래밍 언어를 이해할 수 없다.
- 프로그래밍 언어는 컴퓨터가 이해하는 언어가 아닌 사람이 이해하고 작성하기 쉽게 만들어진 언어다.
- 저급 언어는 ‘컴퓨터가 직접 이해하고 실행 할 수 있는 언어’다.
- 컴퓨터가 이해하고 실행할 수 있는 언어는 저급 언어 뿐이다.
- 그래서 고급 언어로 작성된 소스 코드를 저급 언어, 즉 명령어로 변환 되어야 한다.
- 저급 언어는 두 가지 종류가 있다.
- 기계어
- 0과 1의 명령어 비트로 이루어진 언어
- 이진수와 십육진수로 표현되는 기계어는 컴퓨터만을 위해 만들어진 언어이기 때문에 사람이 읽으면 의미를 이해하기 어렵다. (그래서 어셈블리어가 등장함)
- 어셈블리어
- 0과 1로 표현된 명령어(기계어)를 읽기 편한 형태로 번역한 언어
- 기계어를 읽기 편하게 만든 저급 언어일 뿐이라 복잡한 프로그램을 만들긴 쉽지 않다.
- 기계어
- 복잡한 프로그램을 만들기 위해선 고급 언어가 필요하다.
- 개발자는 고급 언어로 소스 코드를 작성하면 알아서 저급 언어로 변환되어 잘 실행되어 저급 언어로 개발 할 일은 없다고 생각할 수 있다.
- 하지만 하드웨어와 밀접하게 맞닿아 있는 프로그램을 개발하는 임베디드 개발자, 게임 개발자, 정보 보안 분야 등의 개발자는 어셈블리어를 많이 이용한다.
- 또한 어셈블리어를 읽으면 컴퓨터가 어떤 과정으로 실행하는지, 관찰할 수 있다.
컴파일 언어와 인터프리터 언어
- 고급 언어가 저급 언어로 변환하는 방식 2가지
- 컴파일 방식
- 인터프리트 방식
- 컴파일 언어
- 컴파일 방식으로 작동하는 프로그래밍 언어
- 대표적인 컴파일 언어는 C언어가 있다.
- 컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 고급 언어이고 이 과정을 컴파일이라고 한다.
- 그리고 컴파일을 수행해 주는 도구를 컴파일러라고 한다.
- 컴파일러는 개발자가 작성한 코드를 저급 언어로 컴파일 한다. 이때 오류를 하나라도 발견하면 컴파일에 실패한다.
- 컴파일러를 통해 성공적으로 저급 언어로 변환된 코드를 목적 코드라고 한다.
- 인터프리터 언어
- 인터프리트 방식으로 작동하는 프로그래밍 언어
- 대표적인 언어로 Python이 있다.
- 인터프리터에 의해 소스 코드가 한 줄씩 실행되는 고급 언어다.
- 소스 코드를 한 줄씩 저급 언어로 변환하여 실행해 주는 도구를 인터프리터라고 한다.
- 컴파일 언어와 다르게 소스 코드를 한 줄씩 실행하기 때문에 n번째 줄에 문법 오류가 있더라도 n-1번째 줄까지는 올바르게 수행된다.
- 목적 코드는 컴퓨터가 이해하고 실행할 수 있는 저급 언어인 반면, 인터프리터 언어는 마지막에 이를 때까지 한 줄씩 저급 언어로 해석하며 실행하기 때문에 인터프리터 언어가 컴파일 언어보다 느리다.
3-2 명령어의 구조
연산 코드와 오퍼랜드
- 명령어는 연산코드와 오퍼랜드로 구성되어 있다.
- 연산코드는 연산자, 오퍼랜드는 피연산자라고도 부른다.
- 붉은 글씨가 연산 코드, 검은 글씨가 오퍼랜드
- 오퍼랜드
- 연산에 사용할 데이터가 저장된 위치
- 숫자나 문자와 같이 연산에 사용할 데이터를 직접 명시하기 보다는 연산에 사용할 데이터가 저장된 위치, 즉 메모리 주소나 레지스터 이름이 담긴다.
- 주소 필드라고 부른다.
- 오퍼랜드는 명령어 안에 하나도 없을 수도 있고 여러 개 있을 수도 있다.
- 연산코드
- 명령어가 수행할 연산
- 데이터 전송
- MOVE : 데이터를 옮겨라
- STORE : 메모리에 저장하라
- LOAD (FETCH) : 메모리에서 CPU로 데이터를 가져와라
- PUSH : 스택에 데이터를 저장하라
- POP : 스택의 최상단 데이터를 가져와라
- 산술/논리 연산
- ADD / SUBTRACT / MULTIPLY / DIVIDE : 덧셈 / 뺄셈 / 곱셈 / 나눗셈을 수행하라
- INCREMENT / DECREMENT : 오퍼랜드에 1을 더하라 / 오퍼랜드에 1을 빼라
- AND / OR / NOT : AND / OR / NOT 연산을 수행하라
- COMPARE : 두 개의 숫자 또는 TRUE / FALSE 값을 비교하라
- 제어 흐름 변경
- JUMP : 특정 주소로 실행 순서를 옮겨라
- CONDITIONAL JUMP : 조건에 부합할 때 특정 주소로 실행 순서를 옮겨라
- HALT : 프로그램의 실행을 멈춰라
- CALL : 되돌아올 주소를 저장한 채 특정 주소로 실행 순서를 옮겨라
- RETURN : CALL을 호출할 때 저장했던 주소로 돌아가라
- 입출력 제어
- READ (INPUT) : 특정 입출력 장치로부터 데이터를 읽어라
- WRITE (OUTPUT) : 특정 입출력 장치로 데이터를 써라
- START IO : 입출력 장치를 시작하라
- TEST IO : 입출력 장치의 상태를 확인하라
- 데이터 전송
- 명령어가 수행할 연산
주소 지정 방식
- 명령어의 오퍼랜드 필드에 메모리나 레지스터의 주소를 담는 경우가 많아 오퍼랜드 필드를 주소 필드라고 부른다. 여기서 의문! 그냥 <연산코드, 연산 코드에 사용될 데이터> 로 명령어를 구성하면 안될까?
- 안된다! 명령어 길이 때문이다. 명령어가 n비트로 구성되어있고 연산코드 필드가 m비트라면 오퍼랜드 필드의 길이는 연산 코드만큼의 길이를 뺀 n-m 비트가 된다.
- 그렇게 되면 오퍼랜드 필드로 표현할 수 있는 정보의 가짓수는 2-주소 명령어에서는 2^6개 3-주소 명령어에서는 2^4개 밖에 되지 않는다.
- 하지만 오퍼랜드 필드 안에 메모리 주소가 담긴다면 표현할 수 있는 데이터의 크기는 하나의 메모리 주소에 저장할 수 있는 공간만큼 커진다.
- 연산 코드에 사용할 데이터가 저장된 위치, 즉 연산의 대상이 되는 데이터가 저장된 위치를 유효 주소라고 한다.
- 오퍼랜드 필드에 데이터가 저장된 위치를 명시할 때 연산에 사용할 데이터 위치를 찾는 방법을 주소 지정 방식이라고 한다.
- 주소 지정 방식은 유효 주소를 찾는 방법이다.
- 즉시 주소 지정 방식
- 연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시하는 방식
- 가장 간단한 형태의 주소 지정 방식
- 데이터의 크기가 작아지는 단점이 있지만 연산에 사용할 데이터를 메모리나 레지스터로부터 찾는 과정이 없기 때문에 빠르다.
- 직접 주소 지정 방식
- 오퍼랜드 필드에 유효 주소를 직접 명시하는 방식
- 오퍼랜드 필드에서 표현할 수 있는 데이터의 크기는 즉시 주소 지정방식보다 커졌지만 여전히 유효 주소를 표현할 수 있는 범위가 연산 코드의 비트 수만큼 줄어들었다.
- 표현할 수 있는 오퍼랜드 필드의 길이가 연산 코드의 길이만큼 짧아져 표현할 수 있는 유효 주소에 제한이 생길 수 있다.
- 간접 주소 지정 방식
- 유효 주소의 주소를 오퍼랜드 필드에 명시한다.
- 직접 주소 지정 방식보다 표현할 수 있는 유효 주소의 범위가 넓어졌다.
- 다만 두번의 메모리 접근이 필요하기 때문에 앞선 방식들보다 느리다.
- 레지스터 주소 지정 방식
- 직접 주소 지정 방식과 비슷하게 연산에 사용할 데이터를 저장한 레지스터를 오퍼랜드 필드에 직접 명시하는 방법이다.
- 일반적으로 CPU 외부에 있는 메모리에 접근하는 것보다 CPU 내부에 있는 레지스터에 접근하는 것이 더 빠르다.
- 그러므로 레지스터 주소 지정 방식은 직접 주소 지정 방식보다 빠르게 데이터에 접근할 수 있다.
- 다만 표현할 수 있는 레지스터 크기에 제한이 생길 수 있다.
- 레지스터 간접 주소 지정 방식
- 연산에 사용할 데이터를 메모리에 저장하고 그 주소를 저장한 레지스터를 오퍼랜드 필드에 명시하는 방법
- 유효 주소를 찾는 과정이 간접 주소 지정 방식과 비슷하지만, 메모리에 접근하는 횟수가 한 번으로 줄어든다는 장점이 있다.
- 레지스터 간접 주소 지정 방식은 간접 주소 지정 방식보다 빠르다.
즉시 주소 지정 방식 연산에 사용할 데이터
직접 주소 지정 방식 | 유효 주소 (메모리 주소) |
간접 주소 지정 방식 | 유효 주소의 주소 |
레지스터 주소 지정 방식 | 유효 주소 (레지스터 이름) |
레지스터 간접 주소 지정 방식 | 유효 주소를 저장한 레지스터 |
*좀 더 알아보기
- 스택과 큐
- 스택
- 한쪽 끝이 막혀있는 통과 같은 저장 공간
- 막혀있지 않은 쪽으로 데이터를 차곡차곡 저장하고, 저장한 자료를 빼낼 때는 마지막으로 저장한 데이터부터 빼낸다.
- 후입선출이라는 점에서 LIFO(리포)자료 구조라고 부른다.
- 이때 스택에 새로운 데이터를 저장하는 명령어가 PUSH, 스택에 저장된 데이터를 꺼내는 명령어가 POP이다.
- 큐
- 양쪽이 뚫려 있는 통과 같은 저장 공간
- 한쪽으로는 데이터를 저장, 다른 한쪽으로는 저장한 순서대로 데이터를 빼낸다.
- 가장 먼저 저장된 데이터부터 빼내는 데이터 관리방식(선입선출)이라는 점에서 FIFO 자료구조라고도 부른다.
- 스택
- 고급 언어는 사람이 이해하고 작성하기 쉽게 만들어진 언어다.
- 저급 언어는 컴퓨터가 직접 이해하고 실행할 수 있는 언어다.
- 저급 언어는 0과 1로 이루어진 명령어로 구성된 기계어와 기계어를 사람이 읽기 편한 형태로 변역한 어셈블리어가 있다.
- 컴파일 언어는 컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 언어다.
- 인터프리터 언어는 인터프리터에 의해 소스 코드가 한 줄 씩 저급 언어로 변환되어 실행되는 언어다.
- 명령어는 연산 코드와 오퍼랜드로 구성된다. - 연산 코드는 명령어가 수행할 연산을 의미한다.
- 오퍼랜드는 연산에 사용할 데이터 또는 연산에 사용할 데이터가 저장된 위치를 의미한다.
- 주소 지정 방식은 연산에 사용할 데이터 위치를 찾는 방법이다.
'혼자 공부하는 컴퓨터 구조+운영체제' 카테고리의 다른 글
6장 메모리와 캐시 메모리 (1) | 2024.06.04 |
---|---|
5장 CPU 성능 향상 기법 (0) | 2024.06.04 |
4장 CPU의 작동 원리 (1) | 2024.05.19 |
2장 데이터 (0) | 2024.05.17 |
1장 컴퓨터 구조 시작하기 (0) | 2024.05.10 |