[컴퓨터 구조 1] 레지스터의 종류와 주소 지정 방식, 명령어 사이클과 인터럽트
레지스터(Register)
먼저 레지스터란 CPU 내부의 작은 임시 저장 장치를 뜻한다. 말 그대로 필요한 값이나 주소 등을 '임시'로 저장한 장치. 용도에 따라 이름이 다양하고, 제조 회사별 명칭이 상이하다. 책에서 설명한 레지스터의 종류는 8가지!
인출 사이클에 쓰이는 기본 레지스터 4가지
- 프로그램 카운터(PC): 메모리에서 읽어 들일 명령어의 주소를 저장. 명령어 포인터(IP)
- 명령어 레지스터(IR): 방금 메모리에서 읽어 들인 명령어를 저장.
- 메모리 주소 레지스터(MAR): 메모리의 주소를 저장.
- 메모리 버퍼 레지스터(MBR): 메모리에 쓰고 싶은 값이나 메모리로부터 전달받은 값 저장. 메모리 데이터 레지스터(MDR)
즉 PC와 MAR은 주소를, IR과 MBR은 실질적인 값을 저장한다. 저장 내용물의 차이. 이 4개의 레지스터가 어떻게 쓰이는 지를 개략적으로 보기 위해, 인출 사이클(Fetch Cycle)을 먼저 살펴보자. 메모리에 있는 명령어를 CPU로 가져오는 단계를 '인출 사이클'이라고 하는데, 진행은 다음과 같다.

- 읽어올 명령어의 주소를 얻기 위해 프로그램 카운터(PC)에서 메모리 주소 레지스터(MAR)로 주소 버스를 내보냄.
- 제어 장치의 신호에 맞추어 MAR의 값이 각각 제어 버스와 주소 버스를 통해 메모리로 전달
- 해당 주소에 저장된 값(명령어)는 데이터 버스를 통해 메모리 버퍼 레지스터(MBR)로 전달
- PC의 값은 1 증가되어 다음 명령어를 읽어 들일 준비
- MBR에 저장된 값은 명령어 레지스터(IR)로 이동
이외의 레지스터 4가지
- 플래그 레지스터(flag register): ALU 연산 결과에 따른 플래그를 저장
- 부호 플래그(sign flag): 연산 결과의 부호를 나타냄. 1이면 음수, 0이면 양수
- 제로 플래그(zero flag): 연산 결과가 0인지 여부를 나타냄. 1이면 0, 0이면 0 아님
- 캐리 플래그(carry flag): 연산 결과 올림수/빌림수 발생 여부를 나타냄. 1이면 발생, 0이면 아님
- 오버플로우 플래그(overflow flag): 오버플로우 발생 여부를 나타냄. 1이면 발생, 0이면 아님
- 인터럽트 플래그(interrupt flag): 인터럽트 가부 여부를 나타냄. 1이면 가능, 0이면 불가능
- 슈퍼바이저 플래그(supervisor flag): 커널/사용자 모드를 나타냄. 1이면 커널, 0이면 사용자
- 범용 레지스터(general purpose register): 데이터와 주소를 모두 자유로이 저장 가능한 레지스터
- 스택 포인터(stack pointer): 스택의 꼭대기(마지막으로 저장한 값의 위치)를 가리키는 레지스터
- 베이스 레지스터(base register): 메모리의 '기준 주소'를 나타내는 레지스터
주소 지정 방식(addressing mode)
명령어(instruction)는 연산 코드(operation code, 연산자)와 오퍼랜드(operand, 피연산자)로 구성되는데, 이 오퍼랜드의 주소를 유효 주소(effective address)라 한다. 이 유효 주소를 찾는 방법이 '주소 지정 방식'이다.
기본 주소 지정 방식 5가지
- 즉시 주소 지정 방식(Immediate Addressing): 연산에 사용할 데이터를 직접 명시
- 직접 주소 지정 방식(Memory Direct Addressing): 유효 주소(메모리 주소)를 직접 명시
- 간접 주소 지정 방식(Memory Indirect Addressing): 유효 주소의 주소를 명시
- 레지스터 주소 지정 방식(Register Addressing): 유효 주소(레지스터 이름)를 명시
- 레지스터 간접 주소 지정 방식(Register Indirect Addressing): 유효 주소를 저장한 레지스터를 명시
특정 레지스터를 이용한 주소 지정 방식
- 스택 주소 지정 방식(Stack Addressing): 스택 포인터가 주소를 가리킴
- 변위 주소 지정 방식(Displacement Addressing): 오퍼랜드 필드의 값(변위)과 특정 레지스터의 값을 더하여 유효 주소 계산
- 상대 주소 지정 방식(PC Relative Addressing): 오퍼랜드와 프로그램 카운터(PC)의 값을 더하여 유효 주소 계산
- 베이스 레지스터 주소 지정 방식(Base-register Addressing): 오퍼랜드와 베이스 레지스터의 값을 더하여 유효 주소 계산
명령어 사이클(Instruction Cycle)
기본적으로 메모리의 명령어를 CPU로 읽어들이는 '인출 사이클(Fetch Cycle)'과 이를 실행하는 '실행 사이클(Execution Cycle)'로 구성된다.
이때 간접주소방식 등 추가 메모리 접근이 필요한 경우 '간접 사이클(Indirect Cycle)'을, 인터럽트가 발생한 경우 '인터럽트 사이클(Interrupt Cycle)'로 들어간다.
이 중 인터럽트 사이클을 중심으로 봐보자.
- IO는 CPU에 인터럽트 요청 신호(INTR), CPU는 실행 사이클이 끝나고 명령어 인출 전에 항상 인터럽트 여부를 확인
- CPU가 인터럽트 요청을 확인하면, 인터럽트 가능 플래그(IE)를 통해 수용 여부를 확인
- AND(INTR, IE)==1인 경우 현재 실행하던 프로그램을 중단하고 CPU는 PC(프로그램 카운터)와 SR(상태 레지스터)를 스택에 저장
- CPU는 인터럽트 벡터(Interrupt Vector)를 참조해[도식 3번] 메모리에 저장된 인터럽트 서비스 루틴(ISR)을 실행[도식 4번]
- ISR이 끝나면 스택에서 작업을 복구해 실행을 재개[도식 5번]
인터럽트(Interrupt)
그럼 앞에서 계속 언급한 인터럽트는 뭘까? CPU가 작업을 잠시 중단해야하는, 즉 현재 작업보다 더 중요한 일이 있어서 작업을 방해하는 신호를 인터럽트(interrupt)라고 한다.
먼저 동기 인터럽트(synchronous interrupts)는 CPU에 의해 발생하는 인터럽트로, 흔히 예외(exception)라고 부른다. 종류는 이하와 같음
- 폴트(fault): 예외를 처리한 직후, 예외가 발생한 명령어부터 실행을 재개하는 예외
- 트랩(trap): 예외를 처리한 직후, 예외가 발생한 명령어의 다음 명령어부터 실행을 재개하는 예외. 디버깅이나 주소 공간 침해 시 발생
- 중단(abort): CPU가 실행 중인 프로그램을 강제로 중단시킬 수밖에 없는 심각한 오류 시 발생하는 예외
- 소프트웨어 인터럽트(software interrupt): 사용자 모드의 프로그램이 OS 서비스를 제공받기 위해 시스템 호출(system call)을 할 때의 예외
- 무시 가능 인터럽트(maskable interrupt): IE==1일 때만 처리 가능한 인터럽트
- 무시 불가 인터럽트(non maskable interrupt): IE가 0이더라도 강제로 처리하는, 가장 우선순위가 높은 인터럽트. 정전이나 HW 고장 시 발생
출처: [혼자 공부하는 컴퓨터구조+운영체제 Chapter 04]