[혼공컴운] Ch03. 명령어
강민철 - 혼자 공부하는 컴퓨터구조 운영체제
책을 읽으며 개인적으로 정리한 내용입니다.
목차
- 소스코드와 명령어
- 고급 언어와 저급 언어
- 컴파일 언어와 인터프리터 언어
- 목적파일 vs 실행파일
- 명령어의 구조
- 연산 코드와 오퍼랜드
- 주소 지정 방식
✅ 소스코드와 명령어
우리가 작성한 소스코드는
컴퓨터 내부에서 명령어로 변환된다.
프로그래밍 언어는 어떻게 명령어가 되어 실행될까?
⏺ 고급 언어와 저급 언어
고급 언어 : 사람을 위한 언어 -대부분의 프로그래밍 언어
저급 언어 : 컴퓨터가 이해하고 실행 할 수 있는 언어
우리가 고급언어로 작성한 코드는 반드시 저급언어(명령어)로 변환되어야한다.
저급언어는 기계어, 어셈블리어가 있다.
기계어 : 0과 1의 명령어 비트로 이루어진 언어
컴퓨터만을 위해 만들어진 언어라서 의미를 이해하기 어렵다.
어셈블리어 : 0과 1로 표현된 명령어(기계어)를 읽기 편한 형태로 번역한 언어
어셈블리어를 이용해 복잡한 프로그램을 만들기는 쉽지 않다.
그래서 고급언어가 필요하고,
고급언어를 사용함으로써 더 나은 가독성을 보장한다.
변수, 함수 등의 편리한 문법이 제공되어서 복잡한 프로그램을 구현할 수 있다.
HW와 밀접하게 맞닿아있는 프로그램 개발자 (임베디드 개발자, 게임 개발자, 정보보안 등 ) 는 어셈블리어를 많이 이용한다.
⏺ 컴파일 언어와 인터프리터 언어
고급언어가 저급언어로 변환되는 방식이 두가지가 있다.
-> 컴파일 방식, 인터프리트방식
컴파일 언어 : 컴파일 방식으로 작동하는 프로그래밍 언어
인터프리터 언어 : 인터프리트방식으로 작동하는 프로그래밍 언어
✔️ 컴파일언어
소스코드 전체가 저급언어로 변환되어 실행
ex) C언어
컴파일 : 코드 전체가 저급언어로 변환되는 과정
컴파일러 : 해당 과정을 수행하는 도구
* 오류 1개라도 있으면 컴파일 실패한다.
목적코드 : 컴파일러를 통해 저급언어로 변환된 코드
✔️ 인터프리터 언어
인터프리터에 의해 소스코드 한줄씩 실행되는 언어
ex) Python
한줄씩 차례로 실행된다.
인터프리터 : 한줄씩 저급 언어로 변환해 실행해주는 도구
*소스코드 전체를 변환하는 시간을 기다릴 필요가 없다.
* 한줄씩 실행하기 떄문에 N번쨰 줄에 문법 오류가 있어도, N-1번째 줄까지는 올바르게 수행된다.
일반적으로 인터프리터언어는 컴파일언어보다 느리다.
자바같은경우는 인터프리터와 컴파일러를 둘다 사용했었다...
⏺ 목적파일 vs 실행파일
목적파일 : 목적 코드로 이루어진 파일
실행파일 : 실행 코드로 이루어진 파일
목적코드는 컴퓨터가 이루어진 저급 언어이기 떄문에,
실행될수 있는 실행파일이 되기 위해
링킹이라는 작업을 거친다.
✅ 명령어의 구조
하나의 명령어에 존재하는 연산코드 , operand, 주소지정방식을 알아보자.
⏺ 연산 코드와 오퍼랜드
명령어는 연산코드 + 오퍼랜드로 구성되어있다.
연산코드 : 명령어가 수행할 연산 (연산자)
오퍼랜드 : 연산에 사용될 데이터가 저장된 위치 (피연산자)
오퍼랜드
연산코드가 어떤 연산을 하느냐에 따라
오퍼랜드가 1개일수도, 2개일수도, 없을수도 있다
오퍼랜드가 0개 : 0-주소 명령어
오퍼랜드가 1개 : 1-주소 명령어
....
연산코드
- 데이터 전송
- MOVE : 데이터를 옮겨라
- STORE : 메모리에 저장해라
- LOAD (FETCH) : 메모리에서 CPU로 데이터를 가져와라
- PUSH : 스택에 데이터를 저장해라
- POP : 최상단 데이터를 가져와라
- 산술 논리 연산
- ADD, SUBTRACT, MULTIPLY, DIVIDE - 산술연산을 수행하라
- INCREMENT, DECREMENT - 오퍼랜드에 1을 더하라/빼라
- AND, OR, NOT - 해당 연산을 수행하라
- COMPARE - 두 숫자 / TRUE, FALSE 값을 비교하라
- 제어 흐름 변경
- JUMP : 특정 주소로 이동해 실행 순서 변경
- CONTITIONAL JUMP : 특정 조건에 부합시 주소 이동해 실행 순서 변경
- HALT : 프로그램 실행 멈춰라
- CALL : 되돌아올 주소 저장한 채 특정 주소로 실행순서를 옮겨라
- RETURN : CALL 에서 저장한 주소로 돌아가라
- 입출력 제어
- READ (INPUT) : 특정 입출력 장치로부터 데이터 읽어라
- WRITE (OUTPUT) : 특정 입출력 장치로 데이터를 써라
- START IO : 입출력 장치를 시작하라
- TEST IO : 입출력 장치 상태를 확인하라
⏺ 주소 지정 방식
✔️ 왜 오퍼랜드 필드에 메모리/레지스터의 주소를 담는걸까?
왜냐면 명령어의 길이가 정해져 있기 때문이다.
연산코드와 오퍼랜드 (개수가 증가할수록 오퍼랜드 공간 크기는 점점 작아진다)로 표현할 수 있는 비트 수가 작아서
오퍼랜드 필드에 주소를 담게 되면, 데이터의 크기 상관없이 표현할 수 있다.
레지스터의 이름을 명시할 때에도 마찬가지이다.
표현할 수 있는 정보의 가짓수는 레지스터가 저장할 수 있는 공간만큼 커진다.
유효주소 : 연산의 대상이 되는 데이터가 저장된 위치
>> 첫번째 그림에선 10번지, 두번째 그림에선 레지스터 R1
✔️ 주소지정 방식
유효주소를 찾는 방법은 5가지가 있다.
즉시 주소 지정 방식
- 연산에 사용할 데이터를 직접 명시하는 방식 (굉장히 빠르지만 너무 공간이 한정적)
직접 주소 지정 방식
- 오퍼랜드 필드에 유효주소를 직접적으로 명시한다.
- 표현할 수 있는 데이터 크기는 즉시 주소 지정방식보다 커졌지만, 유효주소 표현 범위가 제한이 있다.
간접 주소 지정 방식
- 유효주소의 주소를 오퍼랜드 필드에 명시
- 두번의 메모리 접근이 필요해서 위의 방식들보다 느리다.
레지스터 주소 지정 방식
- 연산에 사용할 데이터가 레지스터에 저장된 경우도 있다.
- 연산에 사용할 데이터가 저장된 레지스터를 오퍼랜드 필드에 직접 명시하는 방법
- CPU 외부 메모리접근하는 것보다는, CPU 내부 레지스터에 접근하는게 더 빠르다
- 레지스터 크기에 제한이 생길 수 있다.
레지스터 간접 주소 지정 방식
- 연산에 사용할 데이터를 메모리에 저장하고, 그 주소를 저장한 레지스터를 오퍼랜드필드에 명시하는 방법
- 간접 주소 지정방식과 비슷하지만, 메모리에 접근하는 횟수가 한번으로 줄어든다.
- 따라서 간접 주소 지정방식보다 빠르다!
references
혼자 공부하는 컴퓨터구조 운영체제 (강민철)