안녕하세요, 루피입니다!
오늘은 컴퓨터의 명령어 처리 방식에 대해 정리해보는 시간을 가져보겠습니다.
바로 시작합니다.
1. 명령어 유형
명령어란 CPU에 특정 작업을 지시하는 기본 단위입니다. 컴퓨터는 오직 기계어만 이해할 수 있지만, 사람이 기계어를 직접다루기는 어렵기 때문에 어셈블리 언어와 같은 저수준 언어를 사용해 명령어를 표현합니다.
어셈블리 언어에서의 명령어 유형
| 명령어 유형 | 설명 | 명령어 |
|---|---|---|
| 데이터 전송 명령어 | 데이터를 메모리에서 레지스터로 이동하는 명령어 | LOAD, STORE, MOVE, PUSH, POP |
| 산술 연산 명령어 | 사칙 연산을 수행하는 명령어 | ADD, SUB, MUL, DIV |
| 논리 연산 명령어 | 참, 거짓을 나타내는 연산을 수행하는 명령어 | AND, OR, XOR, NOT |
| 분기 명령어 | 다음에 실행될 명령어를 지정하는 명령어 | JUMP, CALL, RETURN |
명령어 사용 방법 예시
| 명령어 | 설명 |
|---|---|
| PUSH A | A의 값을 메모리에 삽입 |
| MOVE R1,A | A의 값을 R1으로 이동 |
| ADD R1,A,B | A와 B를 더해서 R1에 저장 |
사용 방법을 보면 한가지 의문이 드실 수 있습니다. 명령어 뒤에 따라오는 데이터의 갯수가 다른 것을 확인 할 수 있는데요. 즉, 연산코드 뒤에 따라오는 오퍼랜드 개수가 다르다는 것이죠.
이것을 바탕으로 우리는 0주소 명령어부터 3주소 명령어까지 나눌 수 있습니다.

간단하게 살펴보자면, 0주소 명령어의 경우 오퍼랜드가 없기에 명령어 길이가 짧습니다. 따라서 메모리 공간을 적게 차지한다는 장점이 있으나 그만큼 유연성이 제한적일 수 있습니다.
반면, 3주소 명령어는 명령어 길이가 길기 때문에 메모리 공간을 많이 차지한다는 단점이 있으나, 그만큼 유연하다는 장점이 있습니다.
2. 명령어 주소 지정 방식
주소 지정 방식이란 연산에 사용될 데이터가 메모리의 어디에 위치 하는지 지정하는 방식으로 CPU가 데이터에 효율적으로 접근하기 위한 다양한 전략이라고 생각하면 쉽습니다.
1) 직접 주소 지정
직접 주소 지정 방식은 어셈블리 언어와 같은 프로그래밍에서 사용되는 주소 지정 방식 중 하나입니다.
이 방식은 명령어에 메모리 주소가 포함되기 때문에 CPU가 해당 주소에 있는 데이터에 직접 접근할 수 있습니다.예를 들어 다음과 같은 명령어가 있다고 가정해 보겠습니다.
LOAD R2, 1000
LOAD는 인출과 관련한 연산코드이며, R2는 레지스터, 1000은 메모리 주소를 나타냅니다. 즉, 메모리 주소 1000에 저장된 데이터에 접근하여 레지스터 R2로 가져오라는 명령입니다.

이 같은 직접 주소 지정 방식은 단순하고 이해하기 쉬우며 메모리에 직접 접근하기 때문에 실행 속도가 빠릅니다. 하지만, 메모리 주소를 명령어에 직접 코딩해야 하기 때문에 프로그램을 수정할 때 변경할 게 많습니다.
2) 간접 주소 지정
간접 주소 지정 방식은 실제 주소가 아닌, 주소를 담고 있는 또 다른 메모리 주소를 가리키는 방식입니다.
한 단계 더 거쳐가기 때문에 ‘간접’이라고 부릅니다. C언어의 포인터와 아주 유사한 개념입니다. 예를 들어 다음과 같은 명령어가 있다고 가정해 봅시다.
Load A, (2000)
괄호 내 2000은 메모리 주소를 가리키는데, 이는 실제 데이터가 저장된 위치를 직접 나타내는 것이 아니라 메모리 주소 2000에 저장된 값을 다시 메모리 주소로 사용한다는 것을 의미합니다.
- 명령어 LOAD A, (2000)에 따라 메모리 주소 2000을 확인합니다.
- 메모리 주소 2000에서 3000이라는 값을 가져옵니다. 이때, 3000은 데이터 값이 아니라 메모리 주소를 의미합니다.
- 이제 CPU는 3000이라는 메모리 주소로 가서 실제 데이터를 가져옵니다.
- 그리고 그 데이터를 레지스터 A로 가져옵니다.

이 방식은 데이터 위치가 자주 바뀌거나 복잡한 데이터 구조를 다룰 때 유용합니다. 하지만, 직접 주소 지정 방식에 비해 메모리 접근이 추가되므로 실행 속도는 더 느릴 수 있습니다.
포인터
포인터는 데이터가 아니라 데이터가 저장된 위치를 가리키는 숫자를 나타냅니다. 예를 들어 C언어에서 포인터를 사용하는 예는 다음과 같습니다.
int var = 15;
int *p = &var; // p는 var의 메모리 주소를 가리킵니다.
cout << var << endl; // 15
cout << &var << endl; //0x16fdfee3c
cout << p << endl; // 0x16fdfee3c
cout << *p <<endl; // 15 : p가 가리키는 주소로 가서 값을 가져옵니다.
3) 즉시 주소 지정
즉시 주소 지정 방식은 데이터를 직접 명령어 안에 포함하는 방식입니다.
즉, 메모리 주소나 레지스터를 통해 데이터를 참조하지 않고, 명령어 자체가 데이터 값을 직접 담고 있습니다. 따라서 연산 처리 속도가 빠르고 효율적입니다. 예를 들어 다음과 같은 명령어가 있다고 가정해 봅시다.
MOV AX, 1234h
MOV는 데이터 전달 명령어이며, AX는 목적지 레지스터, 1234h는 16진수로 표현된 데이터 자체입니다.
따라서 이 명령어는 AX 레지스터에 16진수 값 1234h를 직접 할당하겠다는 의미입니다.
4) 레지스터 (직접) 주소 지정
레지스터 (직접) 주소 지정 방식은 메모리 대신 CPU 안에 있는 레지스터를 사용하는 방법입니다.
예를 들어 다음과 같은 명령어가 있다고 가정해 봅시다.
MOV R1, R2
이 명령어는 R2 레지스터의 내용을 R1 레지스터로 이동시키라는 의미입니다. 이때, R1과 R2 모두 레지스터입니다. 메모리까지 갈 필요 없이 CPU에 있는 레지스터르 직접 참조하기 때문에 속도가 빠릅니다.

5) 레지스터 간접 주소 지정
레지스터 간접 주소 지정 방식은 CPU 내 레지스터를 사용하여 메모리 주소를 간접적으로 참조하는 주소 지정 방식입니다.
즉, 레지스터에 실제 데이터의 메모리 주소가 저장되어 있으며, 이주소를 통해 데이터에 접근합니다. 예를 들어 다음과 같은 명령어가 있다고 가정해 봅시다.
MOV R1, [R2]
이 명령어는 R2 레지스터에 저장된 메모리 주소를 참조하여 그 위치의 데이터를 R1 레지스터로 이동시키라는 의미입니다. 여기서 [R2]는 메모리 주소를 나타냅니다.

이 방식은 메모리 주소 자체가 레지스터에 저장되어 있을 때 유용합니다.
레지스터 방식만 사용하면 되지 않을까?
위 내용을 공부하시면, 사실상 메모리까지 접근하지 않고 레지스터에서 끝내는 것이 결국 가장 효육적인 방식이라는 것을 알 수 있을겁니다. 그렇다면 왜 굳이 이렇게 느린 메모리 주소 지정 방식을 사용하는 걸까요?
모든 데이터를 레지스터에만 올려두고 초고속으로 처리하면 완벽할 것 같지만, 현실적으로는 불가능합니다. 가장 큰 이유는 레지스터의 치명적인 단점, 바로 ‘용량’과 ‘비용 때문입니다.’ 따라서 우리는 항상 좋은 성능에는 비용이 따른다는 것을 알고 있어야 합니다.
오늘도 화이팅입니다!
'CS' 카테고리의 다른 글
| [CS] 5. 주기억 장치 (0) | 2025.07.01 |
|---|---|
| [CS] 4. CPU 동작원리 (0) | 2025.06.20 |
| [CS] 2. 컴퓨터의 데이터 처리 방식 (2) | 2025.06.14 |
| [CS] 1. 컴퓨터 구조의 기본 요소 (2) | 2025.06.14 |
| [CS] OS란 무엇인가? (0) | 2025.03.07 |