[컴퓨터 구조] 명령어 집합

명령어는 컴퓨터가 작업을 하기 위해 필요한 언어로 명령어 집합에 대한 의미와 특성을 살펴보고 학습해보자

명령어 집합

명령어 집합의 의미

요즘의 대부분의 프로그램은 고급언어로 작성

→ 컴파일러와 인터프리터를 통해 기계어로 변환하여 사용해야함

#1 명령어

cpu가 수행할 동작을 2진수 코드로 정의한 것 2진수코드 대신 연상 부호를 사용한 어셈블리 형태의 명령어로 표현

#2 명령어 집합

특정 cpu를 위해 정의된 명령어의 모음

명령어 집합 구조 (Instruction Set Architecture)

작성된 프로그램과 그 프로그램을 수행할 컴퓨터 하드웨어 사이의 인터페이스에 대한 완전한 정의 또는 명세

  • 어떤 연산을 수행할 수 있고 어떤 데이터가 필요한 지 명시
  • 사용할 수 있는 데이터의 표현 방식, 데이터 형식 명시
  • 데이터 위치를 알 수 있는 주소 지정 방식 명시

#1 어셈블리어

컴퓨터 하드웨어가 이해할 수 있는 기계어를 여러 방법을 사용하여 편리하게 만든 컴퓨터 언어

기본적으로 기계어와 1대1 대응하며 하드웨어 종속적 → 생산성이 낮아 많이 사용되지않음

명령어 집합 설계

명렁어 집합을 설계하기 위해서는 어려 사항을 고려해야함 → 하드웨어 기술, 프로그래밍 언어, 컴퓨터 구성, 운영체제 등

#1 연산의 종류

명령어가 프로세서에서 수행할 수 있는 일의 종류를 의미

일반적으로 전송, 처리, 제어, 입출력 연산의 네 가지 존재

#2 데이터 형식

데이터에 가능한 값, 데이터에 실행할 수 있는 명령, 데이터의 의미, 데이터 값을 저장하는 방식을 의미

데이터의 종류를 명시하고 데이터를 식별하는 분류

#3 명령어 형식

명령어 구성 부분을 나타내는 양식을 의미

최소한 연산의 종류를 지정하는 연산 부호를 포함

#4 피연산자의 주소 지정 방식

연산에 따라 필요한 데이티가 존재 → 해당 데이터가 저장되어 있는 주소를 지정하는 방식을 가짐

명령어의 특성

명령어는 컴퓨터가 수행할 수 있는 동작을 2진수 코드로 정의한 것 → 여러 가지 구성 요소를 가짐

  • 연산부호 : 연산의 종류를 명시 (덧셈, 뺄셈)
  • 피연산자 필드 : 연산될 데이터를 위한 정보를 포함 (피연산자의 위치나 데이터)
  • 모드 비트 : 피연산자의 위피에 대한 명시 방법을 나타냄
  • 다음 명령어 주소 필드 : 다음 명령어의 위치를 나타냄

피연산자의 수

초기의 컴퓨터는 데이터의 산술 연산이 주 목적 → 명령어의 기본 연산 또한 산술 연산 기반으로 구성

  • 피연산자가 없는 경우 : halt (프로그램 정지 명령어)
  • 단항 피연산자 : not r1 (not(r1)값을 r1에 저장)
  • 이항 피연산자 : add r1, r2 (r1=r1+r2)
  • 다항 피연산자 : madd r1, r2, r3, r4 (r1=r1+r2+r3+r4)

→ 명령어의 길이를 줄이기 위해 아래와 같은 방법 사용

#1 메모리 주소 대신 레지스터 주소로 피연산자 명시

#2 근원지 피연산자 중 하나를 목적지 피연산자와 겸용

피연산자 필드 중 하나를 줄일 수 있는 방법

#3 묵시적 피연산자 사용

특별한 레지스터가 사용될 경우 해당 피연산자 수를 줄일 수 있음

#4 스택 사용

스택을 사용할 경우 스택 최상위에 해당 피연산자를 저장 → 피연산자가 없이 명령어 사용 가능

명령어의 길이

명령어는 피연산자와 연산 부호로 구성 → 피연산자 및 연산 부호에 따라 명령어의 길이가 변함

  • 고정 길이 명령어 형식 : 명령어의 종류와 명령어에 포함된 구성 요소와 상관없이 명령어의 길이가 모두 일정한 형식
  • 가변 길이 명령어 형식 : 명령어의 종류나 포함된 구성 요소에 따라 다양한 길이의 명령어를 사용하는 명령어 형식

CPU 기본 구성

CPU 기본 구성과 명령어 실행 순서

폰 노이만 모델에서 CPU, 메모리, 입출력장치 제공

CPU는 제어장치와 산술논리장치로 구성 → 연산을 위해 레지스터 사용

  • 프로그램 계수기 (PC, program counter) 다음에 실행할 명령어 주소를 보관하는 레지스터
  • 명령어 레지스터 (IR, instruction register) 가장 최근에 인출한 명령어를 보관하는 레지스터
  • 누산기 (ACC, accumulator) 데이터를 일시적으로 보관하는 레지스터
  • 메모리 주소 레지스터 (MAR, memory address register) 프로세서가 메모리에 접근하기 위한 참조하려는 데이터의 주소
  • 메모리 버퍼 레지스터 (MBR, memory buffer register) 프로세서가 메모리로부터 읽거나 메모리에 저장할 데이터 자체를 보관하기 위한 버퍼

#1 데이터 적재과정 (Load)

프로세서는 데이터가 있는 메모리 주소를 MAR에 보냄

→ MAR이 지정하는 메모리 주소에 있는 데이터를 읽어와 MBR에 저장

→ 프로세서는 MBR에 저장된 데이터를 읽음

#2 데이터 저장과정 (Stroe)

프로세서는 데이터를 저장할 메모리 주소를 MAR에 저장

→ 프로세서는 데이터를 MBR에 저장

→ 메모리는 MAR이 지정하는 위치에 MBR의 내용을 저장

좋은 명령어 집합 구조

명령어 집합 구조는 하드웨어와 소프트웨어 사이의 인터페이스 역할

→ 상위 계층의 소프트웨어를 위해 편리한 기능 제공

→ 하위 계층의 하드웨어를 효과적으로 구현하는 환경 제공

  • 일관성 (cositency) : 일부 명령어의 구조만 알아도 나머지 명령어의 구조를 예측할 수 있어야함
  • 직교성 (orthogonality) : 명령어 구성 요소 사이의 독립성을 유지
  • 적절성 (propriety) : 모든 컴퓨터의 기능은 시스템의 필수 요구 조건에 포함되어야 하고 본질적이지 않거나 기능과 관계없는 부분은 최소화
  • 일반성 (generality) : 하나의 기능을 다양한 목적으로 사용할 수 있는 것을 의미

연산

컴퓨터의 4대 기능을 수행하기 위한 다양한 종류의 연산을 수행하는 명령어 제공

연산의 종류

전송, 처리, 제어, 입출력 연산을 제공

#1 전송 연산

CPU 내의 레지스터와 메모리 사이에 데이터를 교환하는, 적재 및 저장하는 연산

#2 처리 연산

산술논리장치를 사용하여 데이터를 조작하는 연산 → 산술연산, 논리연산, 변환연산을 통해 데이터 조작

#3 제어 연산

CPU의 제어장치가 프로그램의 실행 순서를 제어하는 연산 → 반복문이나 분기문, 프로시저 호출 등의 비순차적으로 실행하기 위한 제어

#4 입출력 연산

CPU 내의 레지스터와 외부 장치 사이의 데이터 이동을 수행하는 연산 (+전송 연산)

분기 명령

분기 명령은 명령어의 흐름을 변경하여 비순차적으로 명령어를 수행

→ chain 방식의 분기는 명령어가 다음 명령어의 위치를 명시하는 방식 → 분기 방식은 명령어의 위치를 명시하지 않고 다음 명령어는 기본적으로 다음 위치에 있다 간주하는 방식 (현재 많이 사용)

분기 명령은 조건에 따라 분기하는 조건 분기와 관계없이 분기하는 무조건 분기 명령으로 구분

#1 조건 분기 명령어

→ 조건 분기의 경우 연산의 조건에 따라 프로그램 흐름을 변경하는 데 사용

이처럼 연산의 조건을 사용하기에 그에 대한 조건을 저장해야함 → flag register의 사용

올림수 (carry), 오버플로우 (overflow), 부호 (sign), 영 (zero) ⇒ 이러한 비트를 사용하여 조건에 맞는 flag register 사용

프로시저의 호출과 복귀

프로시저는 현대 프로그래밍 언어의 핵심 중 하나 → 언어나 사용방법에 따라 서브루틴, 함수, 메소드, 서브프로그램으로 불림

프로그램 내의 중복 코드를 줄임 → 프로그램의 크기 줄고 코드 재사용률을 높임

프로그램 구현의 상세 내역을 숨김

명령어 그룹을 프로시저로 나타나기에 프로그램의 의미 쉽게 파악

→ 이러한 장점이 있는 프로시저를 호출하고 복귀하는 과정에 따라 부담 발생

호출 시 프로시저로의 명령어 인출은 다른 명령어와 같으나 복귀해야할 주소를 저장하는 것이 다른 점

→ 스택에 복귀해야할 주소를 저장하는 호출 규약을 사용하는 등 (calling convention)