에듀테크 프로젝트 대시보드
주소 지정 방식 (Addressing Modes)
명령어는 "무엇을 계산할지"뿐 아니라 "그 피연산자가 어디 있는지"도 지정해야 한다 — 그 방법이 다섯 가지다
ADD R1, X 라는 명령어가 있다고 하자. R1에 무언가를 더해야 하는데,
도대체 X는 무엇을 뜻하는가? X 자체가 더할 값인가? 아니면 값이 저장된 메모리 주소인가?
그것도 아니면 다른 레지스터 안의 값인가? 명령어의 비트 몇 개가 "X를 어떻게 해석할지"를 함께 지정하는데,
이 해석 규칙을 주소 지정 방식(Addressing Mode)이라 부른다. 같은 명령어 폭 안에서 유연성과 속도를
맞바꾸는 설계 선택이다.
피연산자를 찾아가는 "경로"의 길이가 방식마다 다르다. 경로가 짧을수록(메모리를 덜 뒤질수록) 빠르지만, 대신 프로그램이 표현할 수 있는 것도 단순해진다.
MOV R1, #5 — 값 5 자체가 명령어 안에 박혀 있음해석할 것도 없이 명령어 그 자체가 데이터다. 그래서 상수를 레지스터에 넣을 때 흔히 쓴다.
MOV R1, [100] — 명령어 안의 100은 메모리 주소주소로 딱 한 번 가면 값이 있다. 전역 변수처럼 위치가 고정된 데이터에 적합하다.
MOV R1, [[200]] — 200번지에는 값이 아니라 또 다른 주소가 있음"포인터의 포인터" 개념. 한 번 더 거쳐야 진짜 값에 닿는다 — 그만큼 메모리 접근도 두 배다.
ADD R1, R2 — 값이 레지스터 R2 안에 바로 있음메모리 근처에도 안 간다. 레지스터는 CPU 내부에 있어 접근이 사실상 즉시다.
MOV R1, [R2] — R2 안에 메모리 주소가 들어있음C의 포인터 변수와 거의 같은 개념. 레지스터가 "어디를 가리킬지"는 실행 중에 계속 바뀔 수 있다.
아래에 작은 CPU 상태(레지스터 R1·R2 + 8칸짜리 메모리)가 있다. 주소 지정 방식을 골라 한 단계씩
실행해 보면, 같은 "R1에 값 적재"라도 몇 번 메모리를 거치는지가 방식마다 다르다는 걸 체감할 수 있다.
비교를 쉽게 하려고 다섯 방식 모두 R1 ← 피연산자 형태로 통일했다 (ADD 같은 연산 명령어도
피연산자를 찾는 과정 자체는 동일하다).
경로: (아직 실행 전)
| 방식 | 메모리 접근 횟수 | 속도 | 유연성 | 대표 활용 |
|---|---|---|---|---|
| 즉시 (Immediate) | 0회 | 가장 빠름 | 낮음 — 값이 명령어에 고정 | 상수 초기화 (i = 0) |
| 레지스터 (Register) | 0회 | 가장 빠름 | 중간 — 레지스터 값은 바뀌지만 개수가 적음 | 레지스터 간 연산 (R1 += R2) |
| 직접 (Direct) | 1회 | 보통 | 낮음 — 주소가 명령어에 고정 | 전역 변수 접근 |
| 레지스터 간접 (Register Indirect) | 1회 | 보통 | 높음 — 실행 중 레지스터 값만 바꾸면 대상 변경 | 포인터 변수(*p), 배열 순회, 배열 인덱싱(오프셋과 결합) |
| 간접 (Indirect) | 2회 | 가장 느림 | 가장 높음 — 가리키는 주소 자체를 자료구조로 관리 가능 | 포인터 배열, 함수 포인터 테이블, 이중 포인터(**pp) |
고급 언어의 포인터는 사실 주소 지정 방식을 소스 코드 수준에서 그대로 노출한 것이다.
// int 변수 하나와 그걸 가리키는 포인터, 포인터의 포인터 int x = 42; // x 자체에 값 42가 저장됨 int *p = &x; // p 안에는 "x의 주소"가 들어있다 int **pp = &p; // pp 안에는 "p의 주소"가 들어있다 printf("%d", x); // x를 직접 읽음 → 레지스터/직접 주소지정과 대응 printf("%d", *p); // p가 가리키는 곳을 읽음 → 레지스터 간접 주소지정과 대응: MOV R1, [R2] printf("%d", **pp); // pp → p → x, 두 번 따라감 → 간접 주소지정과 대응: MOV R1, [[addr]]
*p 한 번 역참조는 메모리 접근 1회, **pp 두 번 역참조는 메모리 접근 2회 —
포인터를 많이 중첩할수록 프로그램이 실제로 느려지는 이유가 바로 이것이다.
변수 → *p → **pp와 정확히 같은 모양이다.