Skip to Content
독학사독학사 2단계컴퓨터구조13. 명령어 형식과 주소지정 방식

이번 문서의 목표: 이 파일을 다 읽으면 명령어를 오퍼코드와 오퍼랜드로 분해할 수 있고, 즉시·직접·간접·레지스터·레지스터 간접·변위·상대 주소지정 방식 각각에서 유효주소(Effective Address, EA)와 최종 값을 손으로 계산할 수 있다.

왜 주소지정 방식이 여러 가지 필요할까

12편에서 명령 사이클을 다루며 “간접 사이클은 간접 주소지정 방식을 쓸 때만 실행된다”고 언급했다. 그런데 왜 간접 방식 하나로 통일하지 않고 여러 방식을 두는 걸까? 이유는 명령어의 길이는 짧게 유지하면서도, 다양한 방식으로 넓은 메모리 공간에 접근해야 하기 때문이다. 오퍼랜드(피연산자) 필드에 쓸 수 있는 비트 수는 한정되어 있는데, 그 한정된 비트로 “값 자체”, “가까운 주소”, “먼 주소”, “계산이 필요한 주소” 등 다양한 상황에 대응하려면 해석 규칙 자체를 여러 가지로 만들어야 한다.

명령어 형식: 오퍼코드와 오퍼랜드

쉽게 말하면: 명령어는 “무엇을 할지”를 나타내는 오퍼코드와 “어떤 데이터에 대해 할지”를 나타내는 오퍼랜드로 나뉜다.

명령어 형식(instruction format)은 명령어를 이루는 비트열을 몇 개의 필드로 나눈 구조다. 가장 기본적인 구성은 다음과 같다.

  • 오퍼레이션 코드(Operation Code, Opcode): 덧셈·이동·분기 같은 “무엇을 할지”를 나타내는 필드다.
  • 주소지정 방식(addressing mode) 필드: 뒤따르는 오퍼랜드 필드를 “값 그대로”로 읽을지, “주소로” 읽을지, “주소의 주소로” 읽을지를 지정하는 필드다.
  • 오퍼랜드(operand): 실제 값이나 주소를 담는 필드로, 주소지정 방식에 따라 해석이 완전히 달라진다.

공통 예제 환경: 하나의 메모리 그림으로 전부 계산한다

쉽게 말하면: 아래의 같은 메모리·레지스터 상태를 기준으로, 주소지정 방식마다 유효주소와 최종 값이 어떻게 달라지는지 비교한다.

이후 모든 주소지정 방식은 다음과 같은 공통 상태를 기준으로 계산한다.

레지스터
PC(다음 실행할 명령어 주소)500
R1(범용 레지스터)700
메모리 주소저장된 값
500(현재 실행 중인 명령어, 오퍼랜드 필드 = 200)
200900
70050
900300
505(오퍼랜드 필드가 상대 주소지정에 쓰일 때의 변위 값 = 5)

명령어의 오퍼랜드 필드에 적힌 숫자를 200이라고 가정하고, 이 하나의 숫자가 주소지정 방식에 따라 어떻게 다르게 해석되는지 살펴본다.

즉시 주소지정: 오퍼랜드가 곧 값이다

쉽게 말하면: 즉시 주소지정은 오퍼랜드 필드 자체가 사용할 값이므로, 메모리를 한 번도 더 찾아가지 않는다.

즉시 주소지정(immediate addressing mode)은 오퍼랜드 필드에 적힌 숫자를 그대로 데이터 값으로 쓴다. 메모리 접근이 전혀 필요 없어 가장 빠르다.

사용할 값=200\text{사용할 값} = 200
  • 오퍼랜드 필드에 적힌 숫자 200이 그 자체로 데이터다. 메모리 900번지나 다른 어떤 주소도 참조하지 않는다.

즉시 주소지정은 빠르지만, 표현할 수 있는 값의 범위가 오퍼랜드 필드의 비트 수로 제한된다는 단점이 있다. 큰 수를 표현하려면 필드가 커져야 하고, 그러면 명령어 전체 길이도 길어진다.

직접 주소지정: 오퍼랜드가 유효주소다

쉽게 말하면: 직접 주소지정은 오퍼랜드 필드에 적힌 숫자를 메모리 주소로 보고, 그 주소의 내용을 값으로 쓴다.

직접 주소지정(direct addressing mode)은 오퍼랜드 필드 값을 그대로 유효주소로 삼는다.

EA=200EA = 200 사용할 값=M[200]=900\text{사용할 값} = M[200] = 900
  • EAEA(Effective Address, 유효주소): 실제로 값을 가져올 메모리 주소.
  • M[200]M[200]: 메모리 200번지에 저장된 값. 위 표에서 200번지에는 900이 저장돼 있으므로 최종 값은 900이다.

메모리를 한 번 참조한다.

간접 주소지정: 오퍼랜드가 유효주소의 주소다

쉽게 말하면: 간접 주소지정은 오퍼랜드가 가리키는 곳에 진짜 주소가 또 적혀 있어서, 메모리를 두 번 찾아가야 한다.

간접 주소지정(indirect addressing mode)은 12편의 간접 사이클에서 이미 다룬 방식으로, 오퍼랜드 필드가 가리키는 메모리 위치에 “진짜 유효주소”가 저장돼 있다.

EA=M[200]=900EA = M[200] = 900 사용할 값=M[EA]=M[900]=300\text{사용할 값} = M[EA] = M[900] = 300
  • 먼저 200번지를 읽으면 900이라는 값이 나오는데, 이것이 바로 진짜 유효주소다.
  • 그 유효주소 900번지를 다시 읽으면 최종 값 300을 얻는다.

메모리를 두 번 참조하므로 직접 주소지정보다 느리지만, 유효주소 자체를 프로그램 실행 중에 바꿀 수 있어(예: 900번지의 내용을 다른 주소로 바꾸면 같은 명령어가 다른 데이터를 가리키게 된다) 배열이나 포인터 같은 유연한 자료구조를 다루는 데 유리하다.

레지스터 주소지정: 오퍼랜드가 레지스터 번호다

쉽게 말하면: 레지스터 주소지정은 메모리를 아예 거치지 않고, 레지스터 안의 값을 바로 쓴다.

레지스터 주소지정(register addressing mode)은 오퍼랜드 필드가 메모리 주소가 아니라 레지스터 번호를 가리킨다. 오퍼랜드 필드가 “R1을 쓰라”는 뜻이라고 하면 다음과 같다.

사용할 값=R1=700\text{사용할 값} = R1 = 700
  • 메모리 접근이 전혀 없다. 레지스터는 CPU 내부에 있으므로 메모리보다 훨씬 빠르게 접근할 수 있다.

레지스터 간접 주소지정: 레지스터가 유효주소를 담는다

쉽게 말하면: 레지스터 간접 주소지정은 레지스터 안의 값을 유효주소로 보고, 그 주소의 메모리 내용을 가져온다.

레지스터 간접 주소지정(register indirect addressing mode)은 오퍼랜드가 가리키는 레지스터(R1)의 값을 유효주소로 사용한다.

EA=R1=700EA = R1 = 700 사용할 값=M[EA]=M[700]=50\text{사용할 값} = M[EA] = M[700] = 50
  • R1에 저장된 값 700이 유효주소가 되고, 700번지의 내용 50이 최종 값이다.
  • 간접 주소지정과 비슷하지만, 유효주소를 메모리가 아니라 레지스터에서 가져온다는 점이 다르다. 메모리 접근은 한 번만 일어난다.

변위 주소지정: 레지스터 값과 오퍼랜드를 더한다

쉽게 말하면: 변위 주소지정은 레지스터 값에 오퍼랜드 필드의 숫자(변위)를 더해 유효주소를 만든다.

변위 주소지정(displacement addressing mode)은 레지스터 값과 오퍼랜드 필드에 적힌 변위(displacement)를 더해 유효주소를 계산한다. 오퍼랜드 필드가 “R1 + 변위 5”를 뜻한다고 하면 다음과 같다.

EA=R1+5=700+5=705EA = R1 + 5 = 700 + 5 = 705
  • R1=700R1 = 700(기준이 되는 레지스터 값), 55(오퍼랜드 필드에 담긴 변위 값)
  • M[705]M[705]가 실제 최종 값이 되는데, 이 편의 공통 예제 표에는 705번지 값을 별도로 정의하지 않았으므로 “EA=705EA = 705를 계산해 그 번지의 내용을 읽는다”는 절차 자체가 핵심이다.

변위 주소지정은 배열의 특정 원소에 접근할 때 유용하다. R1을 배열의 시작 주소로 두고 변위를 “몇 번째 원소인지”로 삼으면, 반복문을 돌 때마다 변위만 바꿔가며 배열 전체를 순회할 수 있다.

상대 주소지정: PC를 기준으로 삼는다

쉽게 말하면: 상대 주소지정은 변위 주소지정과 계산 방식은 같지만, 기준이 되는 레지스터가 PC라는 점이 다르다.

상대 주소지정(relative addressing mode)은 변위 주소지정의 특수한 경우로, 기준 레지스터가 항상 PC(프로그램 카운터)다. 공통 예제 표에서 505번지의 오퍼랜드 필드 값(변위) 5를 사용한다고 하면 다음과 같다.

EA=PC+5=500+5=505EA = PC + 5 = 500 + 5 = 505
  • PC=500PC = 500(현재 인출 시점 기준의 PC 값), 55(오퍼랜드 필드에 담긴 변위 값)

상대 주소지정은 분기(branch) 명령어에서 특히 많이 쓰인다. “지금 위치에서 몇 칸 앞으로 뛰어라”는 식으로 목적지를 표현하면, 프로그램이 메모리의 어느 위치에 적재되든 상대적인 거리만 맞으면 항상 정확하게 동작하기 때문이다. 이런 특성을 재배치 가능(relocatable)하다고 표현한다.

시험 함정: 변위 주소지정과 상대 주소지정은 계산식이 똑같이 “기준값 + 변위”이지만, 기준이 되는 것이 범용 레지스터(R1 등)인지 PC인지로 구분한다. 이 둘을 같은 개념으로 뭉뚱그리면 “상대 주소지정의 기준 레지스터는?”과 같은 문제에서 틀리기 쉽다.

주소지정 방식 전체 비교표

방식유효주소 계산식이 편의 예시로 구한 EA메모리 참조 횟수
즉시해당 없음(오퍼랜드가 값 자체)해당 없음0회
직접EA=AEA = AEA=200EA = 2001회
간접EA=M[A]EA = M[A]EA=M[200]=900EA = M[200] = 9002회
레지스터해당 없음(레지스터가 값 자체)해당 없음0회
레지스터 간접EA=REA = REA=R1=700EA = R1 = 7001회
변위EA=R+AEA = R + AEA=700+5=705EA = 700 + 5 = 7051회
상대EA=PC+AEA = PC + AEA=500+5=505EA = 500 + 5 = 5051회
  • AA: 오퍼랜드 필드에 담긴 주소 또는 변위 값
  • RR: 지정된 범용 레지스터의 값
  • PCPC: 현재 인출 시점의 프로그램 카운터 값

자주 틀리는 점

  • 직접 주소지정과 간접 주소지정의 메모리 참조 횟수(1회 대 2회)를 혼동하는 경우가 매우 많다. “오퍼랜드가 곧 유효주소”면 직접, “오퍼랜드가 가리키는 곳에 유효주소가 또 있다”면 간접이다.
  • 레지스터 주소지정(메모리 참조 0회)과 레지스터 간접 주소지정(메모리 참조 1회)을 같은 것으로 착각하기 쉽다. “레지스터의 값 자체를 쓰는지” 아니면 “레지스터의 값을 주소로 보고 메모리를 한 번 더 찾아가는지”의 차이다.
  • 변위 주소지정과 상대 주소지정을 계산식만 보고 같은 것으로 여기는 실수가 잦다. 기준 레지스터가 범용 레지스터인지 PC인지가 핵심 구분점이다.

핵심 정리

  • 명령어는 오퍼레이션 코드(연산 종류)와 오퍼랜드(값 또는 주소)로 구성되며, 오퍼랜드의 해석 규칙이 곧 주소지정 방식이다.
  • 즉시(EA 없음, 참조 0회) → 직접(EA=AEA=A, 참조 1회) → 간접(EA=M[A]EA=M[A], 참조 2회) 순으로 메모리 참조 횟수가 늘어난다.
  • 레지스터 주소지정(참조 0회)과 레지스터 간접 주소지정(EA=REA=R, 참조 1회)은 메모리 접근 여부로 구분된다.
  • 변위 주소지정(EA=R+AEA=R+A)과 상대 주소지정(EA=PC+AEA=PC+A)은 계산식은 같지만 기준이 범용 레지스터인지 PC인지로 구분되며, 상대 주소지정은 분기 명령어의 재배치 가능성에 활용된다.
  • 같은 오퍼랜드 필드 값이라도 주소지정 방식에 따라 최종적으로 쓰이는 값이 완전히 달라진다.

마무리 복습

문제 14지선다
오퍼랜드 필드에 적힌 값이 200이고 직접 주소지정 방식을 쓸 때, 200번지에 저장된 값이 900이라면 최종적으로 사용되는 값은?
문제 24지선다
간접 주소지정 방식에서 오퍼랜드 필드 값이 200이고 M[200] = 900, M[900] = 300일 때 최종 값은?
문제 34지선다
레지스터 주소지정과 레지스터 간접 주소지정의 차이로 옳은 것은?
문제 44지선다
R1 = 700이고 오퍼랜드 필드의 변위 값이 5일 때, 변위 주소지정 방식의 유효주소(EA)는?
문제 54지선다
상대 주소지정 방식에 대한 설명으로 옳은 것은?
문제 64지선다
PC = 500이고 오퍼랜드 필드의 변위 값이 5일 때, 상대 주소지정 방식의 유효주소(EA)는?

참고 자료

Last updated on