오늘은 명령어 세트에 대해서 알아보겠습니다.
1. 명령어 세트
1) 명령어 세트 개요
CPU의 기능은 명령어들에 의하여 결정됩니다. 명령어들의 종류와 수는 CPU마다 약간씩 다른데, 어떤 한 CPU를 위해 정의되어 있는 명령어들의 집합을 명령어 세트라고 합니다. 명령어 세트를 설계하기 위해서는 다음과 같은 사항들을 먼저 결정해야 합니다.
- 연산 종류: CPU가 수행할 연산들의 수와 종류 및 복잡도
- 데이터 유형: 연산이 수행될 데이터들의 유형, 데이터의 길이(비트 수)와 수의 표현 방식(정수, 부동소수점 수) 등
- 명령어 형식: 명령어의 길이, 오퍼랜드 필드들의 개수와 길이 등
- 주소지정 방식: 오퍼랜드의 주소를 지정하는 방식
명령어 세트(instruction set): 한 CPU를 위해 정의되어 있는 명령어들의 집합
오퍼랜드(operand): 연산에 사용하는 데이터 혹은 그것이 담기는 위치(=피연산자)
오퍼랜드 필드(operand Field): 오퍼랜드가 담기는 영역
오늘은 이들중에서 연산종류, 명령어 형식, 주소지정 방식에 대해서 알아보고자 합니다.
2. 연산의 종류
1) CPU의 기본적인 연산 종류
CPU가 수행할 수 있는 연산들의 종류는 컴퓨터에 따라 매우 다양합니다. 그 중에서도 기본적인 연산들을 나열해보겠습니다.
- 데이터 전송
- 레지스터와 레지스터, 기억장치와 기억장치, 레지스터와 기억장치 사이에서 데이터를 이동하는 동작
- 기억장치의 주소를 계산해야 하는 경우도 있음 - 산술 연산
- 덧셈, 뺄셈, 곱셈 및 나눗셈과 같은 기본적인 산술 연산
- 부호를 가진 정수, 부동소수점 수에 대한 산술적 연산도 이에 포함 - 논리 연산
- 데이터의 각 비트들 간에 대한 AND, OR, NOT 및 exclusive-OR등과 같은 논리연산 - 입출력(I/O)
- CPU와 외부장치들 간의 데이터 이동을 위한 동작
- 특수한 I/O 명령어들과 주소지정 방식이 필요 - 프로그램 제어
- 명령어 실행 순서를 변경하는 연산
- 분기, 서브루틴 호출
분기: 특정주소로 점프해 실행위치 변경
서브루틴: 특정 작업을 실행 후 원래 위치로 복귀, 함수의 개념
2) 서브루틴 호출
분기는 이전 포스팅인 명령어 파이프라이닝 에서 짚고 넘어갔었습니다.
[컴퓨터 구조] 명령어 파이프라이닝
오늘은 CPU의 프로그램 처리 속도를 향상시키는 명령어 파이프 라이닝에 대해서 알아보겠습니다.1. 명령어 파이프라이닝1) 명령어 파이프라이닝 개요CPU의 성능은 컴퓨터시스템의 프로그램 처리
5g-0.tistory.com
이번에는 서브루틴 호출에 대해서 살펴보겠습니다.
서브루틴 호출은 '함수'의 개념입니다. 특정 작업을 실행하고, 다시 원래 위치로 복귀하는 특성이 있습니다.
서브루틴에서 사용되는 기본적인 두가지 명령어를 보겠습니다.
- CALL 명령어: 서브루틴을 호출하는 명령어
- RET 명령어: 서브루틴으로부터 원래 프로그램으로 복귀(return)시키는 명령어
예시를 통해 서브루틴에 대해 자세하게 알아보겠습니다.

주 프로그램과 2개의 서브루틴으로 이루어진 그림입니다. 옆의 번지수는 제가 임의로 넣었습니다.
주 프로그램을 실행했을때 명령어 번지수를 10번지부터 시작합니다. 진행하며 내려오면서 CALL SUB1을 통해 SUB1을 수행합니다.
SUB1에서는 CALL SUB2 명령어를 두번 실행하며 SUB2를 두번 수행합니다.
RET 명령어는 서브루틴 종료 후 원래 프로그램으로 돌아가게 합니다.
원래 프로그램으로 돌아가기 위해, CALL, RET 명령어를 실행할때는 스택을 반드시 사용해야합니다.
X번지에 위치한 서브루틴을 호출하는 CALL X 명령어의 실행 과정을 분석해보겠습니다.
# CALL X 명령어 실행과정
t0: MBR <- PC
t1: MAR <- SP, PC <- X
t2: M[MAR] <- MBR, SP <- SP - 1
t0: 현재 프로그램 카운터(PC)에 들어있는 명령어 주소를 메모리 버퍼 레지스터(MBR)로 복사합니다.
-> 함수 호출시 돌아올 주소를 나중에 스택에 저장해두어야 하므로, 우선 PC의 값을 MBR에 임시 보관하는것입니다.
t1: 메모리 주소 레지스터(MAR)에 스택포인터(SP)의 값을 적재하고, PC에 호출하고자 하는 함수의 시작주소 X를 로드합니다.
-> 스택에 저장할 주소로 스택포인터가 가리키는 위치를 사용하고, CPU는 함수로 점프하는것 입니다.
t2: MBR에 저장해둔 반환주소를 MAR를통해 스택에 기록합니다. 스택포인터는 하나 감소시켜서, 스택이 한칸 차지하게 만듭니다.
다음은 RET 명령어를 자세하게 알아보겠습니다.
# RET 명령어
t0: SP <- SP + 1
t1: MAR <- SP
t2: PC <- M[MAR]
t0: 스택 포인터를 하나 증가시킵니다.
-> 스택에 저장된 복귀주소의 값을꺼내기 위해 SP를 증가시켜 복귀 주소가 있는 위치를 가리키게 합니다.
t1: 메모리 주소 레지스터(MAR)에 스택 포인터(SP)의 값을 적재합니다.
-> 스택에서 꺼내고자 하는데이터가 저장되어 있는 위치가 SP가 가리키는 메모리 주소이므로, 그 주소를 MAR에 담아야 합니다.
t2: MAR에 있는 값을 불러와 PC에 적재합니다.
-> 복귀주소를 PC에 로드함으로써, 함수 호출전으로 돌아가 프로그램 실행을 이어갑니다.
그림을 통해 스택의 상황을 살펴보겠습니다.

위의 서브루틴 예시 그림에서의 스택 상황을 그림으로 표현했습니다.
SUB1이 실행됐을때 복귀할 주소인 13을 저장해놓고, 다음 서브루틴 프로그램 실행에서도 복귀주소를 저장해놓습니다.
스택은 후입선출의 개념이기 때문에 이와같은 구조가 가능해집니다.
3. 명령어 형식
1) 명령어 형식 개요
명령어는 CPU에 의해 실행될 때 제공해야할 모든 정보를 포함하고 있어야 합니다. 그들 중에서 기본적인 요소들을 나열해보겠습니다.
- 연산 코드(Operation Code): 수행될 연산을 지정(LOAD, ADD 등)
- 오퍼랜드(Operand): 연산을 수행하는데 필요한 데이터 혹은 데이터의 주소
- 다음 명령어 주소(Next Instruction Address): 현재의 명령어 실행이 완료된 후에 다음 명령어를 인출할 위치
각 연산은 한개 혹은 두개의 입력 오퍼랜드들과 한개의 결과 오퍼랜드를 가질 수 있습니다. 데이터는 CPU레지스터 혹은 기억장치에 위치합니다. 다음 명령어 주소는 분기 혹은 호출 명령어와 같이 실행 순서를 변경하는 경우에만 필요합니다.
각 명령어는 일련의 비트들에 의해 표현되며, 비트의 수는 위의 정보들을 나타내는데 필요한 만큼 사용됩니다. 명령어를 구성하는 비트들은 용도에 따라 몇개의 필드들로 나눌 수 있는데, 필드의 수와 배치 방식 및 각 필드에 포한되는 비트 수를 정의한 것을 명령어 형식(instruction format)이라고 합니다.
명령어 형식(instruction format): 명령어를 구성하는 필드의 종류와 개수, 배치 방식 및 필드 당 비트 수를 정의하는 형식
명령어의 길이, 즉 비트 수는 일반적으로 CPU가 한번에 처리할 수 있는 데이터의 길이와 같습니다. 예를들어 16비트 CPU는 한번에 16비트 단위의 데이터 처리가 가능한데, 그 CPU의 명령어 길이도 16비트입니다. 따라서 명령어의 각 필듸으 수와 길이는 그 범위 내에서 결정되어야 합니다.
그림을 통해 알아보겠습니다.

위의 그림에는 연산 코드 필드에 4비트, 오퍼랜드1 필드에 4비트, 오퍼랜드2 필드에 8비트씩 할당되었습니다.
연산 코드의 비트 수는 CPU가 수행할 수 있는 연산들의 수를 결정해줍니다. 이 예에서는 2^4 = 16가지의 연산을 수행할 수 있습니다.
오퍼랜드 필드는 오퍼랜드가 어떤것이지에 따라 필요한 비트수가 달라질 수 있으며, 배정되는 비트들의 수에 따라 각각의 범위가 결정됩니다.
- 데이터: 표현가능한 수의 크기가 결정
- 기억장치 주소: CPU가 오퍼랜드 인출을 위하여 직접 주솔르 지정할 수 있는 기억장치 영역의 범위가 결정
- 레지스터 번호: 데이터 저장에 사용될 수 있는 내부 레지스터들의 수가 결정
예시로, 오퍼랜드1은 레지스터 번호를 지정하고, 오퍼랜드2는 기억장치 주소를 지정한다고 가정하겠습니다.
사용할 수 있는 레지스터의 개수는 2^4 = 16, 기억장치 주소 범위는 2^8 = 256이기에 0~255번지가 됩니다.
2) 명령어 형식 설계
제한된 수의 비트들을 이용하여 명령어 형식을 설계하는 방법을 알아보겠습니다.
먼저 명령어의 비트들을 연산의 종류와 수에 따라 필요한 만큼 연산 코드 필드에 배정하고, 나머지 비트들은 오퍼랜드들을 위해 배정합니다.
예시를 위해 두개의 데이터에 대하여 덧셈을 수행하는 ADD 명령어를 살펴보겠습니다.
ADD X : AC <- AC + M[X]
이 명령어는 '기억장치 X번지의 내용과 누산기(AC)의 내용을 더하고, 그 결과를 AC에 저장하라' 입니다.
이처럼 명령어가 한 개의 오퍼랜드만 포함하는 것을 1-주소 명령어라고 합니다.
다른 ADD 명령어도 보겠습니다.
ADD R1, R2 : R1 <- R1 + R2
이와같은 명령어에는 2개의 오퍼랜드 필드만 있으면 됩니다. 이와 같은 명령어를 2-주소 명령어라고 합니다.
마찬가지로 3개의 오퍼랜드가 사용되면 3-주소 명령어 입니다.
각 명령어 형식에 따라 연산이 어떻게 바뀌는지 알아보겠습니다. 다음 식을 통해 알아보겠습니다.
X = (A+B) * (C-D)



똑같은 내용의 프로그램을 수행하는데도 1-주소, 2-주소, 3-주소 명령어 각각의 명령어 양에는 차이가 있습니다.
3-주소 명령어를 사용했을때, 프로그램이 가장 짧아진다는 장점이 있지만, 레지스터의 수와 기억장치 용량이 고정된 상태에서 이 명령어 형식을 사용하면 명령어의 비트수가 늘어나게 됩니다. 결과적으로 프로그램의 길이는 줄어들지만 저장하기 위한 기억장치 용량은 줄어들지 않고, 명령어 해독 과정이 더 복잡해진다는 단점이 있습니다.
4. 주소지정 방식
1) 주소지정 방식 개요
명령어의 길이가 늘어나면 오퍼랜드 필드와 각 필드의 비트 수가 증가될 수 있습니다. 하지만 일반적으로 명령어 비트의 수와 CPU가 처리하는 단어의 길이가 같도록 제한됩니다. 그와 같이 제한된 수의 명령어 비트들을 이용하여 사용자로하여금 가능한 다양한 방법으로 오퍼랜드를 지정하고 더 큰 용량의 기억장치를 사용할수있도록 하는 여러가지 주소지정 방식이 사용되었습니다. 이를 설명하기 위해 다음과 같은 표기들을 사용하겠습니다.
- EA: 유효주소, 데이터가 저장된 기억장치의 실제주소
- A: 명령어 내의 주소 필드 내용(오퍼랜드가 기억장치 주소)
- R: 명령어 내의 레지스터 번호(오퍼랜드가 레지스터 번호)
- (A): 기억장치 A의 내용
- (R): 레지스터 R의 내용
주소지정방식: 주소 비트들을 이용하여 오퍼랜드의 유효주소를 결정하는 방법
2) 주소지정 방식의 종류
주소지정 방식의 다양한 종류들을 알아보겠습니다.
2.1) 직접 주소지정 방식
EA = A
명령어 내 오퍼랜드 필드의 내용이 데이터의 유효 주소로 사용하여 연산에 필요한 데이터를 인출하는 방식으로, 가장 간단한 방식입니다.
데이터 인출을 위하여 한 번의 기억장치 액세스만 필요하며, 유효 주소 결정을 위한 다른 절차나 계산은 필요하지 않습니다.
하지만 직접 액세스할 수 있는 기억장치 주소 공간이 오퍼랜드 필드의 비트 수에 의해 제한되는 단점이 있습니다.
2.2) 간접 주소지정 방식
EA = (A)
오퍼랜드가 가리키는 기억장치의 내용을 유효 주소로 사용하여 연산에 필요한 데이터를 인출하며 두번의 기억장치 액세스가 필요한 방식입니다. 이 방식을 위하여 명령어 형식은 간접 비트(I)가 포함되어야 합니다. 0과 1로 구분되어 1이면 간접, 0이면 직접입니다.
직접 주소 지정방식의 문제점인, 주소필드의 길이가 짧기 떄문에 주소를 지정할 수 있는 기억장치 범위가 제한된다는 점을 해결하기 위해 나온 방식입니다. 간접 주소지정방식에서는 여러 단계의 간접지정도 가능합니다.
2.3) 묵시적 주소지정 방식
명령어 실행에 사용될 데이터가 묵시적으로 지정되어 있는 방식입니다.
예를 들어, SHL 명령어는 누산기(AC)의 내용을 좌측으로 시프트(shift)하라는 명령어 입니다. 해당 명령어는 오퍼랜드 필드가 없지만 자동적으로 누산기에 대하여 연산이 수행됩니다. 이러한 방식에는 스택의 PUSH, POP 명령어도 포함됩니다.
이 방식의 가장 큰 장점은 오퍼랜드가 없거나 한 개 뿐이기 때문에 명령어 길이가 짧다는 점 입니다.
2.4) 즉시 주소지정 방식
명령어 내에 포함되어 있는 데이터를 연산에 직접 사용하는 방식입니다.
오퍼랜드 필드의 내용이 연산에 즉시 사용될 수 있는 데이터이기에 별도의 인출과정이 필요하지 않습니다. 이러한 방식은 변수의 초기값을 어떤 상수값으로 세트하는데 주로 사용됩니다. 실행사이클이 짧아진다는 장점이 있지만, 사용할 수 있는 수의 크기가 오퍼랜드 필드의 비트 수에 의해 제한된다는 단점이 있습니다.
2.5) 레지스터 주소지정 방식
EA = R
명령어의 오퍼랜드가 가리키는 레지스터에 저장되어 있는 데이터를 연산에 사용하는 방식입니다.
레지스터들의 수는 오퍼랜드 필드의 비트 수에 의해 결정됩니다.
장점으로는 명령어 형식에서 오퍼랜드 필드의 비트수가 적어도 되고, 기억장치를 액세스할 필요가 없으며, 명령어 실행시간이 훨씬 짧다는 점이 있습니다. 하지만 이 방식을 사용하면 데이터가 저장될 수 있는 위치가 CPU 내부 레지스터로 제한된다는 단점이 있습니다.
2.6) 레지스터 간접 주소지정 방식
EA = (R)
지정된 레지스터의 내용을 유효주소로 사용하여, 그 주소가 가리키는 기억장치로부터 읽어온 데이터를 연산에 사용하는 방식입니다.
주소를 지정할 수 있는 기억장치의 영역은 레지스터 길이에 달려있습니다. 이 방식에서는 기억장치에 한번의 액세스가 필요합니다.
2.7) 변위 주소지정 방식
EA = A + (R)
지정된 레지스터의 내용과 명령어 내 오퍼랜드를 더하여 유효주소를 결정하는 방식입니다.
두 개의 오퍼랜드를 가지며, 하나는 변위를 나타내는 주소 A이고, 다른 오퍼랜드는 레지스터 번호 R입니다.
R이 가리키는 레지스터의 내용을 A와 더함으로써 결정됩니다.
대표적으로 세가지 방식이 있습니다.
- 상대 주소지정 방식
- EA = A + (PC)
- 레지스터로 프로그램 카운터 사용 - 인덱스 주소지정 방식
- EA = A + (IX)
- 인덱스 레지스터의 내용과 변위 A를 더하여 유효주소 결정 - 베이스-레지스터 주소지정 방식
- EA = A + (BR)
- 베이스 레지스터의 내용과 명령어내 오퍼랜드를 더하여 유효주소 결정
작성하면서 이전 개념들을 계속 복습할 수 있어서 좋은것같습니다.
'CS > 컴퓨터 구조' 카테고리의 다른 글
[컴퓨터 구조] 산술논리연산장치(ALU)의 구성요소와 정수의 표현 (0) | 2025.04.09 |
---|---|
[컴퓨터 구조] 상용 프로세서들의 명령어 형식 (2) | 2025.04.08 |
[컴퓨터 구조] 명령어 파이프라이닝 (0) | 2025.04.02 |
[컴퓨터 구조] CPU의 구조와 명령어 실행 (4) | 2025.03.27 |
[컴퓨터 구조] 컴퓨터의 발전 과정 (2) | 2025.03.26 |