레지스터와 명령어의 관계
CPU는 명령어를 실행할 때 레지스터를 중심으로 동작한다.
명령어는 보통 다음과 같은 정보로 구성된다.
- Opcode: 어떤 연산을 할 것인가
- Addressing Mode: 피연산자를 어떻게 해석할 것인가
- Register 번호: 어떤 레지스터를 사용할 것인가
- Operand / Address: 값 또는 주소 정보
명령어는 메모리에서 가져와 Instruction Register(IR)에 저장되고, CPU는 IR에 저장된 명령어를 해석하여 실행한다.
Direct Addressing Mode
Direct Mode는 명령어 안에 메모리 주소를 직접 담는 방식이다.
예를 들어 명령어의 operand 필드가 8비트라면, 표현 가능한 주소 범위는 0~255로 제한된다.
즉, CPU나 명령어 형식에서 operand에 할당된 비트 수가 작으면 접근 가능한 메모리 주소 범위도 제한된다.
Indirect Addressing Mode
Indirect Mode는 명령어 안에 실제 데이터 주소를 직접 넣지 않고, 주소가 저장되어 있는 메모리 위치나 레지스터를 가리키는 방식이다.
즉, 명령어가 가리키는 곳에는 데이터가 있는 것이 아니라, 최종적으로 접근해야 할 주소가 들어 있다.
예시
Direct Mode:
LOAD R1, [100]
→ 100번지의 값을 R1에 로드
Indirect Mode:
LOAD R1, [100]
→ 100번지에 저장된 값을 주소로 해석하고,
그 주소에 있는 값을 R1에 로드
명령어 하나만으로 표현할 수 없는 큰 주소에 접근해야 한다면, 여러 명령어를 사용해 레지스터에 목표 주소를 계산하거나 구성한 뒤, 그 레지스터를 통해 메모리에 접근할 수 있다.
ex)
MOV R0, 4 MUL R0, R0, 4 ; R0 = 16 MUL R0, R0, 16 ; R0 = 256 LOAD R2, [R0] ; 256번지 접근`
명령어의 1operand 필드가 작아 직접 주소를 담을 수 없더라도, 레지스터에 주소 값을 계산해서 넣은 뒤 Register Indirect 방식으로 접근할 수 있다.
레지스터 기억하면 좋은 4가지
- IR (Instruction Register) → 현재 실행할 명령어
- PC (Program Counter) → 다음 명령어 주소
- MAR (Memory Address Register) → 접근할 메모리 주소
- MDR (Memory Data Register) → 메모리에서 읽거나 쓸 데이터 흐름 : PC → MAR → Memory → MDR → IR
프로그램 작동 원리와 상관관계
- Fetch
- PC가 가리키는 주소를 MAR로 보냄
- 메모리에서 명령어 읽어서 MDR → IR
- Decode
- IR 해석 (opcode, addressing mode 등)
- Execute
- ALU + 레지스터 사용해서 연산 수행
추가적인 Addressing 모드
Register Addressing
ADD R1, R2 → 메모리 안 건드리고 레지스터끼리 연산 → operand가 메모리 주소나 즉시값이 아니라 레지스터 이름 → 가장 빠름
Immediate Addressing
MOV R1, 5 → 값 자체가 명령어에 포함됨
RISC vs CISC
RISC = 단순한 명령어를 빠르게 많이 실행하는 구조 CISC = 복잡한 명령어 하나로 많은 일을 처리하는 구조
RISC
Reduced Instruction Set Computer
명령어 종류를 줄이고, 각 명령어를 단순하게 만든 구조.
LOAD R1, [100]
LOAD R2, [104]
ADD R3, R1, R2
STORE [108], R3특징:
- 명령어가 단순함
- 명령어 길이가 비교적 일정함
- 대부분 레지스터 중심 연산
- 메모리 접근은 LOAD / STORE로 분리
- 2파이프라이닝에 유리함
대표 예시:
ARM, RISC-V
CISC
Complex Instruction Set Computer
복잡한 명령어를 제공해서 한 명령어가 여러 작업을 수행할 수 있는 구조.
ADD [108], [100], [104]
의미상:
Memory[108] = Memory[100] + Memory[104]
특징:
- 명령어가 복잡함
- 명령어 길이가 가변적인 경우가 많음
- 메모리 operand를 직접 다루는 명령이 많음
- 한 명령어가 여러 단계 작업을 수행할 수 있음
- 디코딩이 복잡함
대표 예시:
x86, x86-64
핵심 차이
| 구분 | RISC | CISC |
|---|---|---|
| 철학 | 단순 명령어 여러 개 | 복잡 명령어 적게 |
| 명령어 길이 | 비교적 고정 | 가변 길이 |
| 메모리 접근 | LOAD/STORE 중심 | 명령어가 직접 메모리 접근 가능 |
| 연산 위치 | 주로 레지스터 | 레지스터 + 메모리 |
| 디코딩 | 단순 | 복잡 |
| 파이프라이닝 | 유리 | 상대적으로 어려움 |
면접 대비 질문
-
Instruction Register(IR)의 역할은 무엇인가요? IR은 현재 실행 중인 명령어를 저장하는 레지스터. 명령어 실행 과정에서: Fetch → IR에 저장 → Decode → Execute 즉 CPU가 “지금 무엇을 해야 하는지”를 보관하는 핵심 레지스터
-
Fetch–Decode–Execute 사이클을 설명해보세요. Fetch : PC가 가리키는 주소에서 명령어를 가져옴
Decode : 명령어를 해석 (opcode, operand)
Execute: 연산 수행 및 결과 저장이 과정에서:
- PC: 다음 명령어 위치
- IR: 현재 명령어
- MAR/MDR: 메모리 접근
-
Direct addressing의 한계는 무엇인가요? 명령어의 operand 필드 크기에 의해 접근 가능한 주소 범위가 제한
-
Indirect addressing을 사용하는 이유는 무엇인가요? 주소 표현의 한계를 극복하고 더 큰 메모리 공간에 접근하기 위해 사용. 또한 포인터처럼 동적으로 주소를 변경할 수 있어 유연성이 높습니다.(주소를 명령어에 고정하지 않고, 레지스터 안의 값으로 정한다)
- 메모리 접근이 한 번 더 발생 → 성능 저하
Direct Addressing → 명령어 안에 주소가 박혀 있어서 고정적 Indirect Addressing → 레지스터/메모리에 들어있는 값을 주소로 사용해서 유동적