주소 지정 방식 (Addressing Mode)
핵심 인사이트 (3줄 요약)
명령어에서 피연산자(Operand)의 실제 주소를 계산하는 방법이다. 즉시(Immediate), 직접(Direct), 간접(Indirect), 레지스터(Register), 인덱스(Index) 등 다양한 방식이 존재하며, 명령어 집합의 유연성과 메모리 효율성을 결정하는 핵심 요소다.
Ⅰ. 개요 (필수: 200자 이상)
개념: 주소 지정 방식(Addressing Mode)은 CPU 명령어가 피연산자의 유효 주소(Effective Address)를 결정하는 규칙과 메커니즘이다.
💡 비유: 도서관에서 책을 찾는 방법과 같다. 책이 손에 있다(즉시), 책장 번호를 안다(직접), 안내데스크에서 위치를 물어본다(간접), 내 서랍에 있다(레지스터), 책장 번호 + 칸 번호로 찾는다(인덱스).
등장 배경 (필수: 3가지 이상 기술):
- 기존 문제점: 초기 컴퓨터는 고정된 주소 방식만 지원하여 메모리 공간 낭비가 심했고, 배열·포인터 등 복잡한 데이터 구조 접근이 비효율적이었다.
- 기술적 필요성: 프로그램의 재배치(Relocation), 위치 독립 코드(Position Independent Code), 동적 메모리 할당 등을 지원하기 위해 유연한 주소 계산 방식이 필요했다.
- 시장/산업 요구: 컴파일러 최적화, 운영체제 메모리 관리, 고급 언어의 포인터 연산 등을 효율적으로 구현하기 위한 하드웨어 지원이 요구되었다.
핵심 목적: 명령어 길이를 최소화하면서도 넓은 메모리 공간에 유연하게 접근하고, 프로그램 실행 효율을 극대화하는 것이다.
Ⅱ. 구성 요소 및 핵심 원리 (필수: 가장 상세하게)
구성 요소 (필수: 최소 4개 이상):
| 구성 요소 | 역할/기능 | 특징 | 비유 |
|---|---|---|---|
| 즉시(Immediate) | 명령어 내에 데이터 직접 포함 | 메모리 접근 불필요, 빠름 | 책이 손에 있음 |
| 직접(Direct) | 명령어에 유효 주소 직접 명시 | 주소 범위 제한, 간단 | 책장 번호를 바로 앎 |
| 간접(Indirect) | 주소를 가리키는 주소 사용 | 유연하지만 2회 메모리 접근 | 사서에게 위치 물어봄 |
| 레지스터(Register) | 레지스터 내용을 피연산자로 사용 | 가장 빠름, 레지스터 수 제한 | 내 서랍에서 꺼냄 |
| 레지스터 간접 | 레지스터가 메모리 주소 보관 | 빠르고 유연 | 서랍에 적힌 위치로 감 |
| 인덱스(Indexed) | 베이스 + 인덱스로 주소 계산 | 배열 접근에 최적 | 책장 + 칸 번호 |
| PC 상대(PC Relative) | 현재 PC + 오프셋 | 위치 독립 코드, 분기 | 현재 위치에서 3걸음 |
구조 다이어그램 (필수: ASCII 아트):
┌─────────────────────────────────────────────────────────────────┐
│ 주소 지정 방식 개요도 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ │
│ │ 명령어 │ │
│ │ ┌────┬─────┐ │ │
│ │ │Opcode│Adr │ │ │
│ │ └────┴─────┘ │ │
│ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 주소 계산 방식 선택 │ │
│ │ ┌─────────┬─────────┬─────────┬─────────┐ │ │
│ │ │ 즉시 │ 직접 │ 간접 │ 레지스터 │ │ │
│ │ │Immediate│ Direct │Indirect │ Register│ │ │
│ │ └────┬────┴────┬────┴────┬────┴────┬────┘ │ │
│ └───────┼─────────┼─────────┼─────────┼─────────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │데이터 │ │메모리 │ │메모리 │ │레지스터│ │
│ │직접 │ │[Adr] │ │[Ptr] │ │ │ │
│ └────────┘ └────────┘ └────────┘ └────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 복합 주소 지정 방식 │ │
│ │ │ │
│ │ 인덱스: Base + Index × Scale + Disp │ │
│ │ ┌────────────────────────────────────────┐ │ │
│ │ │ 유효주소 = [Base] + [Index]×Scale + Displacement │ │
│ │ └────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
동작 원리 (필수: 단계별 상세 설명):
① 명령어 인출 → ② Opcode 해석 → ③ 주소 지정 방식 식별 → ④ 유효 주소 계산 → ⑤ 데이터 접근
- 1단계 (명령어 인출): PC가 가리키는 메모리 위치에서 명령어를 읽어 IR(Instruction Register)에 저장
- 2단계 (Opcode 해석): 명령어의 Opcode 필드를 분석하여 수행할 연산 종류 결정
- 3단계 (주소 지정 방식 식별): Addressing Mode 필드를 확인하여 피연산자 찾기 방법 결정
- 4단계 (유효 주소 계산): 해당 방식에 따라 실제 데이터가 있는 유효 주소(Effective Address) 계산
- 5단계 (데이터 접근): 계산된 유효 주소로 메모리 또는 레지스터에서 데이터 읽기/쓰기
각 방식별 상세 동작:
┌────────────────────────────────────────────────────────────────┐
│ 즉시 주소 지정 (Immediate Addressing) │
├────────────────────────────────────────────────────────────────┤
│ 명령어: [Opcode][#상수] │
│ 동작: Operand = 상수 (메모리 접근 없음) │
│ 예: ADD R1, #10 → R1 = R1 + 10 │
│ 장점: 빠름 (메모리 접근 0회) │
│ 단점: 상수 크기가 명령어 길이에 제한 │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ 직접 주소 지정 (Direct Addressing) │
├────────────────────────────────────────────────────────────────┤
│ 명령어: [Opcode][Address] │
│ 동작: EA = Address, Operand = Memory[EA] │
│ 예: LOAD R1, 1000 → R1 = Memory[1000] │
│ 장점: 단순함 │
│ 단점: 주소 범위가 명령어 길이에 제한 (32비트면 4GB) │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ 간접 주소 지정 (Indirect Addressing) │
├────────────────────────────────────────────────────────────────┤
│ 명령어: [Opcode][@Address] │
│ 동작: EA = Memory[Address], Operand = Memory[EA] │
│ 예: LOAD R1, @1000 → R1 = Memory[Memory[1000]] │
│ 장점: 넓은 주소 공간, 동적 주소 지정 가능 │
│ 단점: 느림 (메모리 접근 2회) │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ 레지스터 주소 지정 (Register Addressing) │
├────────────────────────────────────────────────────────────────┤
│ 명령어: [Opcode][Reg] │
│ 동작: Operand = Register[Reg] │
│ 예: ADD R1, R2 → R1 = R1 + R2 │
│ 장점: 가장 빠름 (레지스터 접근만) │
│ 단점: 레지스터 수 제한 │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ 레지스터 간접 주소 지정 (Register Indirect) │
├────────────────────────────────────────────────────────────────┤
│ 명령어: [Opcode][(Reg)] │
│ 동작: EA = Register[Reg], Operand = Memory[EA] │
│ 예: LOAD R1, (R2) → R1 = Memory[R2] │
│ 장점: 빠르고 유연, 포인터 연산에 적합 │
│ 단점: 레지스터에 주소가 있어야 함 │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ 인덱스 주소 지정 (Indexed Addressing) │
├────────────────────────────────────────────────────────────────┤
│ 명령어: [Opcode][Base][Index] 또는 [Base+Disp] │
│ 동작: EA = Base + Index (또는 EA = Register + Displacement) │
│ 예: LOAD R1, 100(R2) → R1 = Memory[R2 + 100] │
│ 장점: 배열, 구조체 접근에 최적 │
│ 단점: 주소 계산 오버헤드 │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ PC 상대 주소 지정 (PC Relative Addressing) │
├────────────────────────────────────────────────────────────────┤
│ 명령어: [Opcode][Offset] │
│ 동작: EA = PC + Offset │
│ 예: JUMP +100 → PC = PC + 100 │
│ 장점: 위치 독립 코드, 분기 명령에 효율적 │
│ 단점: 접근 범위가 Offset 크기에 제한 │
└────────────────────────────────────────────────────────────────┘
핵심 알고리즘/공식 (해당 시 필수):
유효 주소(Effective Address) 계산 공식:
1. 즉시: EA = 없음 (Operand = 상수)
2. 직접: EA = Address field
3. 간접: EA = Memory[Address field]
4. 레지스터: EA = 없음 (Operand = Register[R])
5. 레지스터 간접: EA = Register[R]
6. 인덱스: EA = Register[Base] + Register[Index] × Scale + Displacement
7. PC 상대: EA = PC + Offset
메모리 접근 횟수:
- 즉시: 0회
- 직접: 1회
- 간접: 2회
- 레지스터: 0회
- 레지스터 간접: 1회
- 인덱스: 1회
코드 예시 (필수: Python 또는 의사코드):
"""
주소 지정 방식 시뮬레이터
CPU의 다양한 주소 지정 방식을 Python으로 구현
"""
class AddressingModeSimulator:
"""CPU 메모리와 레지스터를 시뮬레이션하는 클래스"""
def __init__(self, memory_size=1024):
# 메모리 (1KB)
self.memory = [0] * memory_size
# 범용 레지스터 (R0-R7)
self.registers = [0] * 8
# 프로그램 카운터
self.pc = 0
# 상태 레지스터
self.flags = {'Z': 0, 'N': 0, 'C': 0, 'V': 0}
def immediate(self, value):
"""
즉시 주소 지정 (Immediate Addressing)
명령어 내의 상수를 직접 반환
"""
return value # 메모리 접근 없음
def direct(self, address):
"""
직접 주소 지정 (Direct Addressing)
명령어에 지정된 주소에서 데이터 읽기
"""
return self.memory[address] # 메모리 접근 1회
def indirect(self, address):
"""
간접 주소 지정 (Indirect Addressing)
메모리[주소]가 가리키는 위치에서 데이터 읽기
"""
effective_address = self.memory[address] # 메모리 접근 1회
return self.memory[effective_address] # 메모리 접근 2회
def register_direct(self, reg_num):
"""
레지스터 주소 지정 (Register Direct)
레지스터 내용을 직접 반환
"""
return self.registers[reg_num] # 메모리 접근 없음
def register_indirect(self, reg_num):
"""
레지스터 간접 주소 지정 (Register Indirect)
레지스터가 가리키는 메모리 위치에서 읽기
"""
effective_address = self.registers[reg_num]
return self.memory[effective_address] # 메모리 접근 1회
def indexed(self, base_reg, index_reg, scale=1, displacement=0):
"""
인덱스 주소 지정 (Indexed Addressing)
EA = Base + Index × Scale + Displacement
"""
effective_address = (
self.registers[base_reg] +
self.registers[index_reg] * scale +
displacement
)
return self.memory[effective_address]
def pc_relative(self, offset):
"""
PC 상대 주소 지정 (PC Relative Addressing)
EA = PC + Offset
"""
effective_address = self.pc + offset
return self.memory[effective_address]
def auto_increment(self, reg_num):
"""
자동 증가 주소 지정 (Auto-increment)
데이터 읽기 후 레지스터 자동 증가
스택 Pop, 배열 순회에 사용
"""
address = self.registers[reg_num]
data = self.memory[address]
self.registers[reg_num] += 1 # 또는 데이터 크기만큼
return data
def auto_decrement(self, reg_num):
"""
자동 감소 주소 지정 (Auto-decrement)
레지스터 감소 후 데이터 읽기
스택 Push에 사용
"""
self.registers[reg_num] -= 1
address = self.registers[reg_num]
data = self.memory[address]
return data
# 사용 예시
if __name__ == "__main__":
cpu = AddressingModeSimulator()
# 메모리 초기화
cpu.memory[100] = 42 # 주소 100에 값 42
cpu.memory[200] = 300 # 주소 200에 또 다른 주소 300
cpu.memory[300] = 99 # 주소 300에 값 99
# 레지스터 초기화
cpu.registers[0] = 100 # R0 = 100
cpu.registers[1] = 50 # R1 = 50 (인덱스용)
# 각 주소 지정 방식 테스트
print("=== 주소 지정 방식 시뮬레이션 ===")
# 1. 즉시 주소 지정
result = cpu.immediate(10)
print(f"즉시(10): {result}")
# 2. 직접 주소 지정
result = cpu.direct(100)
print(f"직접(100): {result}") # 42
# 3. 간접 주소 지정
result = cpu.indirect(200)
print(f"간접(200): {result}") # 99 (200→300→99)
# 4. 레지스터 주소 지정
result = cpu.register_direct(0)
print(f"레지스터(R0): {result}") # 100
# 5. 레지스터 간접 주소 지정
result = cpu.register_indirect(0)
print(f"레지스터 간접((R0)): {result}") # 42
# 6. 인덱스 주소 지정
# R0(100) + R1(50) + 0 = 150, memory[150] 읽기
cpu.memory[150] = 77
result = cpu.indexed(0, 1, scale=1, displacement=0)
print(f"인덱스(R0+R1): {result}") # 77
# 7. PC 상대 주소 지정
cpu.pc = 1000
cpu.memory[1050] = 88
result = cpu.pc_relative(50)
print(f"PC 상대(PC+50): {result}") # 88
Ⅲ. 기술 비교 분석 (필수: 2개 이상의 표)
장단점 분석 (필수: 최소 3개씩):
| 장점 | 단점 |
|---|---|
| 다양한 데이터 구조 접근 지원 | 하드웨어 복잡도 증가 |
| 명령어 길이 단축 가능 | 명령어 해석 시간 증가 |
| 위치 독립 코드 작성 가능 | CPI(Cycles Per Instruction) 증가 가능 |
| 컴파일러 최적화 용이 | 구현 시 검증 복잡 |
| 코드 크기 절약 | 설계 비용 증가 |
대안 기술 비교 (필수: 최소 2개 대안):
| 비교 항목 | 다양한 주소 지정 | Load/Store만 | 메모리-메모리 |
|---|---|---|---|
| 핵심 특성 | ★ 유연성 최고 | 단순함, 파이프라인 효율 | 명령어 수 최소 |
| 성능 | 복잡한 연산 빠름 | ★ 일반적으로 빠름 | 메모리 대역폭 의존 |
| 복잡도 | 높음 | ★ 낮음 | 중간 |
| 코드 밀도 | ★ 높음 | 낮음 | 높음 |
| 적합 환경 | CISC (x86) | ★ RISC (ARM, RISC-V) | 초기 컴퓨터 |
| 대표 아키텍처 | Intel x86, VAX | ARM, RISC-V, MIPS | IBM 360 |
★ 선택 기준:
- RISC 설계: Load/Store 아키텍처로 단순화, 모든 연산은 레지스터에서 수행
- CISC 설계: 다양한 주소 지정 방식으로 코드 밀도 향상, 복잡한 연산 한 명령어로 처리
- 임베디드: 코드 크기 중요하면 CISC 방식, 전력/단순성 중요하면 RISC 방식
주소 지정 방식별 성능 비교:
| 방식 | 메모리 접근 | 명령어 크기 | 주소 범위 | 용도 |
|---|---|---|---|---|
| 즉시 | 0 | 큼 (데이터 포함) | 제한 | 상수 |
| 직접 | 1 | 큼 (주소 포함) | 제한 | 전역 변수 |
| 간접 | 2 | 작음 | 무제한 | 포인터 |
| 레지스터 | 0 | 작음 | - | 지역 변수 |
| 레지스터 간접 | 1 | 작음 | 무제한 | 포인터 연산 |
| 인덱스 | 1 | 중간 | 무제한 | 배열, 구조체 |
| PC 상대 | 1 | 작음 | 제한 | 분기, 위치 독립 |
기술 진화 계보 (해당 시):
[단일 주소 지정] → [다중 주소 지정] → [Load/Store 아키텍처] → [복합 주소 지정]
(초기) (CISC) (RISC) (현대 x86-64)
Ⅳ. 실무 적용 방안 (필수: 기술사 판단력 증명)
기술사적 판단 (필수: 3개 이상 시나리오):
| 적용 분야 | 구체적 적용 방법 | 기대 효과 (정량) |
|---|---|---|
| 컴파일러 최적화 | 지역 변수는 레지스터, 배열은 인덱스, 상수는 즉시 방식 자동 선택 | 실행 속도 30~50% 향상 |
| OS 커널 개발 | PC 상대 주소로 위치 독립 커널 모듈 작성 | 메모리 단편화 40% 감소 |
| 임베디드 시스템 | 코드 밀도 높은 주소 지정 방식 선택으로 ROM 크기 절약 | ROM 크기 20~30% 절감 |
실제 도입 사례 (필수: 구체적 기업/서비스):
- 사례 1 (Intel x86-64): 복잡한 주소 지정 방식(ModR/M + SIB 바이트)으로
[Base + Index×Scale + Displacement]형태 지원. 16개의 주소 지정 방식으로 레거시 호환성과 성능 동시 확보. 컴파일러가 최적 방식 선택하여 평균 명령어 길이 3.1바이트 달성. - 사례 2 (ARM Cortex-A): Load/Store 아키텍처 기반, 레지스터 간접과 인덱스 중심. Thumb-2 모드에서 16비트/32비트 혼합으로 코드 밀도 30% 향상. 스마트폰 시장 점유율 95% 이상.
- 사례 3 (RISC-V): 단순한 Load/Store 방식만 사용, 하드웨어 복잡도 대폭 감소. 40개의 기본 명령어로 리눅스 부팅 성공. 설계 검증 비용 50% 절감.
도입 시 고려사항 (필수: 4가지 관점):
- 기술적: 파이프라인 효율, 캐시 적중률, 분기 예측 영향, 레거시 호환성
- 운영적: 디버깅 복잡도, 컴파일러 지원, 개발자 학습 곡선, 디어셈블리 가독성
- 보안적: 주소 계산 오버플로우, 버퍼 오버플로우 공격, ASLR(Address Space Layout Randomization) 호환
- 경제적: 칩 설계 비용, 검증 비용, 전력 소모, 생산 단가
주의사항 / 흔한 실수 (필수: 최소 3개):
- ❌ 간접 주소 지정 남용: 2회 메모리 접근으로 성능 저하, 레지스터 간접으로 대체
- ❌ 인덱스 계산 오버플로우: 주소 계산 시 정수 오버플로우로 잘못된 메모리 접근
- ❌ PC 상대 주소 범위 초과: Offset 제한을 넘어 분기 시 링크 오류 발생
- ❌ 정렬 미준비: 인덱스 주소 계산 결과가 메모리 정렬 요구사항 위반
관련 개념 / 확장 학습 (필수: 최소 5개 이상 나열):
📌 주소 지정 방식 핵심 연관 개념 맵
┌─────────────────────────────────────────────────────────────────┐
│ 주소 지정 방식 핵심 연관 개념 맵 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 명령어 형식 ←──→ [주소 지정 방식] ←──→ 메모리 계층 │
│ ↓ ↓ ↓ │
│ CPU 구조 파이프라인 캐시 메모리 │
│ ↓ ↓ ↓ │
│ 레지스터 해저드 가상 메모리 │
│ │
└─────────────────────────────────────────────────────────────────┘
| 관련 개념 | 관계 | 설명 | 문서 링크 |
|---|---|---|---|
| 명령어 형식 | 선행 개념 | 주소 지정 방식이 명령어 내에서 표현되는 구조 | [명령어 형식](./instruction_format.md) |
| 명령어 사이클 | 후속 개념 | 주소 지정 방식이 명령어 실행 사이클에서 처리되는 과정 | [명령어 사이클](./instruction_cycle.md) |
| CPU 파이프라인 | 확장 개념 | 다양한 주소 지정 방식이 파이프라인 효율에 미치는 영향 | [파이프라인](./pipeline.md) |
| 메모리 계층 | 관련 기술 | 주소 지정 방식에 따른 캐시/메모리 접근 패턴 | [캐시 메모리](./cache_memory.md) |
| RISC vs CISC | 대안 개념 | 주소 지정 방식의 복잡도에 따른 아키텍처 분류 | [RISC CISC](./risc_cisc.md) |
| 가상 메모리 | 응용 개념 | 가상 주소와 물리 주소 변환에서의 주소 지정 | [가상 메모리](./virtual_memory.md) |
| 어셈블리 언어 | 실무 응용 | 다양한 주소 지정 방식의 어셈블리 표현 | [어셈블리](./assembly.md) |
🔗 문서 간 연결 원칙:
- 모든 관련 개념은 상호 링크로 연결 (양방향 참조)
- 각 개념 문서의 "관련 개념" 섹션에도 역으로 링크
- 독자가 하나의 문서에서 시작하여 관련 지식 전체를 탐색 가능하게 구성
Ⅴ. 기대 효과 및 결론 (필수: 미래 전망 포함)
정량적 기대 효과 (필수):
| 효과 영역 | 구체적 내용 | 정량적 목표 |
|---|---|---|
| 성능 | 최적 주소 지정으로 메모리 접근 최소화 | 기존 대비 20~40% 향상 |
| 코드 크기 | 효율적 주소 지정으로 명령어 수 절감 | 코드 크기 15~30% 감소 |
| 전력 | 메모리 접근 감소로 전력 소모 절감 | 전력 10~20% 절감 |
| 호환성 | 위치 독립 코드로 이식성 향상 | 이식 비용 50% 감소 |
미래 전망 (필수: 3가지 관점):
- 기술 발전 방향: AI 가속기(NPU, TPU)에서는 텐서 접근 최적화를 위한 특수 주소 지정 방식 등장. 스택 메모리, 뱅크 인터리빙 등 메모리 계층별 최적화된 주소 지정.
- 시장 트렌드: RISC-V 등 오픈 소스 아키텍처에서는 단순 Load/Store 방식 선호. 클라우드/Edge 컴퓨팅에서는 코드 밀도와 전력 효율 균형 필요.
- 후속 기술: 하드웨어 가속 주소 계산, 컴파일러 자동 주소 지정 최적화, 보안 강화를 위한 암호화 주소 지정(Encrypted Addressing).
결론: 주소 지정 방식은 CPU 아키텍처의 유연성과 효율성을 결정하는 핵심 설계 요소다. RISC와 CISC 간 트레이드오프를 이해하고, 컴파일러 최적화와 메모리 계층 구조를 고려한 설계가 필수적이다.
※ 참고 표준: IEEE 754 (부동소수점), ARM Architecture Reference Manual, Intel 64 and IA-32 Architectures Software Developer's Manual, RISC-V ISA Specification
어린이를 위한 종합 설명 (필수)
주소 지정 방식을 쉽게 이해해보자!
주소 지정 방식은 마치 도서관에서 책을 찾는 여러 가지 방법과 같아요.
첫 번째 이야기: 책이 손에 있어요 (즉시 주소 지정) 어떤 책은 이미 내 손에 들려 있어요. 도서관에 가지 않아도 돼요. 이게 가장 빠른 방법이에요. 컴퓨터에서도 숫자 5를 더할 때, 5가 명령어 안에 직접 들어 있으면 메모리에 가지 않아도 돼요.
두 번째 이야기: 책장 번호를 알아요 (직접 주소 지정) 책이 3번 책장에 있다는 걸 알아요. 3번 책장으로 바로 가면 돼요. 컴퓨터에서도 "100번 주소에 있는 데이터를 읽어줘"라고 하면 바로 100번으로 가요.
세 번째 이야기: 사서 아저씨에게 물어봐요 (간접 주소 지정) 어떤 책이 어디 있는지 모르겠어요. 사서 아저씨에게 물어보니 "300번 책장에 있어요"라고 알려줬어요. 그래서 300번으로 갔죠. 이건 두 번 걸리지만, 어려운 문제를 해결할 수 있어요.
네 번째 이야기: 내 서랍에 있어요 (레지스터 주소 지정) 자주 보는 책은 내 책상 서랍에 넣어둬요. 꺼내 쓰기 제일 편해요. 컴퓨터에서도 자주 쓰는 데이터는 레지스터라는 특별한 공간에 넣어둬요. 가장 빠르죠!
다섯 번째 이야기: 책장 + 칸 번호 (인덱스 주소 지정) 만화책을 찾을 때, 5번 책장의 3번 칸을 찾아요. "책장 번호 + 칸 번호"를 합쳐서 위치를 알아내죠. 컴퓨터에서도 배열을 찾을 때 이렇게 해요.
이렇게 다양한 방법으로 데이터를 찾아서, 컴퓨터가 빠르고 똑똑하게 일할 수 있어요!