본문 바로가기
Computer Science/Computer Architecture

[컴퓨터 구조] 명령어 사이클, 인터럽트

by 진현개발일기 2024. 10. 2.

■ 명령어 사이클 (Instruction Cycle)

우리가 실행하고 있는 프로세스는 수 많은 명령어로 구성이 되어있다.

CPU는 이 명령어를 하나씩 실행하게 되고, 각각의 명령어들은 일정한 주기로 반복되며 실행되어진다.

이렇게 하나의 명령어를 처리하는 정형화된 주기를 명령어 사이클이라고 한다.

 

[단계]

일단 아래와 같이 크게 두 가지의 사이클이 반복된다.

 

(1) 인출 사이클 (Fetch Cycle)

아래 레지스터(Register) 관련 포스팅에서 메모리로부터 명령어를 CPU 내 IR(Instruction Register)로 갖고 오는 단계까지가 인출 사이클의 과정이다.

 

이와 같이 메모리로부터 실행해야할 명령어를 CPU로 가져오는 단계를 '인출 사이클'이라고 한다.

https://yjhdevelopdiary.tistory.com/231

 

[컴퓨터 구조] 레지스터 (Register)

■ 레지스터레지스터는 CPU 내부의 작은 임시저장장치이다.프로그램 속 명령어 & 데이터는 실행 전후로 반드시 관련 값들이 레지스터에 저장됨. 그렇기에 레지스터 값만 잘 관찰해도 프로그램

yjhdevelopdiary.tistory.com

 

(2) 실행 사이클 (Execution Cycle)

위에서 명령어를 가져왔다면, 이제 실행하면 된다. CPU로부터 가져온 명령어를 제어장치가 해석하고 제어 신호를 발생시키는 단계를 실행 사이클이라고 한다.

 

프로그램을 이루는 수많은 명령어들은 위 인출, 실행 사이클을 반복적으로 실행한다.

* 하지만 모든 명령어들이 항상 이렇게 간단히 실행되는 것은 아니다.

(3) 간접 사이클 (Indirect Cycle)

아래 포스팅에서 볼 수 있듯이 명령어를 가져왔을 때 곧바로 실행할 수 있는 데이터 대신에 유효주소의 주소를 가져오는 상황이 있을 수 있다 (간접주소지정방식). 이럴 때에는 다시 한 번 메모리에 접근해야 한다.

이러한 상황에서는 간접 사이클을 통해 명령어를 가져오게 된다.

https://yjhdevelopdiary.tistory.com/230

 

[컴퓨터 구조] 명령어, 주소 지정 방식

■ 명령어 구조명령어는 '무엇을 대상'으로 '어떤 작동'을 해야하는 지에 관한 데이터들이 내포되어 있다.이를 아래와 같이 표현할 수 있다.위 예시에서 노란색 배경은 '더해라'의 동작을 담고

yjhdevelopdiary.tistory.com

 

■ 인터럽트 (Interrupt)

간단히 말해서 'CPU가 수행하고 있는 작업을 방해하는 신호''인터럽트'라고 한다. 

위와 같이 CPU가 작업을 잠시 중단해야 할 정도라면 CPU의 자원을 집중시켜야하는 순간에 발생할 것이다.

다양한 인터럽트의 종류를 훑어보다 보면 그 구체적인 상황들이 어떠한 것이 있는지 엿볼 수 있게된다.

 

[종류]

 

(1) 동기 인터럽트 (Synchronous Interrupts)

CPU에 의해 직접적으로 발생하는 인터럽트이다. CPU가 실행하는 프로그래밍에서 예외적인 상황에 마주했을 때 발생하는 인터럽트를 동기 인터럽트 혹은 예외 (Exception)라고 부른다.

 

예외에는 크게 네 가지의 종류가 있다.

[예외 종류]

이름 설명
폴트
(Fault)
예외를 처리한 직후 예외가 발생한 시점의 명령어부터 다시 실행하는 예외를 의미한다.

(ex)
어떠한 명령어를 실행할 때 필요한 데이터가 보조기억장치에 있어가지고 잠시 CPU 폴트를 발생시킨 후 보조기억장치에 있는 데이터를 메모리로 가져와 저장해야 할 때 해당 업무를 수행한 뒤 CPU 폴트가 발생한 명령어부터 다시 실행하게 된다.
트랩
(Trap)
예외를 처리한 직후 예외가 발생한 시점 바로 이후의 명령어부터 다시 실행한다.

(ex)
디버깅 중 원하는 코드에서 프로그램의 실행을 멈추게할 수 있다. 프로그램 중단 및 디버깅 이후 다시 프로그램을 실행한다면 디버깅 부분 이후부터 작업을 재개하게 되는데 이처럼 예외가 발생한 명령어의 다음 명령어부터 실행하는 예외를 트랩(Trap)이라고 한다.
중단
(Abort)
CPU가 실행 중인 프로그램을 강제로 꺼버릴 수 밖에 없는 심각한 오류가 발생했을 때 발생하는 예외이다.
소프트웨어 인터럽트
(Software Interrupts)
시스템 호출이 발생했을 때 나타난다.

 

(2) 비동기 인터럽트 (Asynchronous Interrupts)

주로 입출력 장치에 의해 발생하는 인터럽트이다. 예로 키보드 및 마우스가 입력을 받아들일 때 이를 처리하기 위해서 CPU에게 인터럽트 신호를 보내게 된다.

 

일반적으로 사람들이 칭하는 인터럽트는 비동기 인터럽트를 의미한다. 이러한 비동기 인터럽트는 또 다른 이름을 갖고 있는데 하드웨어 인터럽트(Hardware Interrupt)라고 불리기도 한다. CPU는 입출력 작업 중 명령어의 효율적인 처리를 위해 하드웨어 인터럽트를 사용한다.

 

예로 CPU가 제어신호를 통해 프린터의 출력을 명령했다고 가정해보자, 이후 만약 CPU가 프린트 완료 여부를 주기적으로 확인해야하는 번거로움이 있다면 원활하게 작업을 하기가 어려울 것이다. 이를 방지하기 위해 CPU가 직접 프린터로가서 완료 여부를 확인하는 것이 아니라 프린터가 직접 CPU에게 인터럽트를 발생시켜 작업 완료에 대한 상황을 보고해주는 것이 하드웨어 인터럽트의 예이다.

 

이러한 하드웨어 인터럽트를 받게 되었을 때 CPU가 해당 인터럽트를 처리하는 방식은 아래와 같다.

 

[인터럽트 처리 순서]

(1) 입출력장치는 CPU에게 인터럽트 요청 신호를 보낸다.

(2) CPU는 실행 사이클이 끝난 뒤 그 다음 명령어 인출 전에 인터럽트 여부를 확인한다.

(3) CPU가 인터럽트 요청을 확인했다면 인터럽트 플래그(Interrupt Flag)를 통해 현재 인터럽트를 받아들일 수 있는 상황인지를 체크한다.

(4) 인터럽트를 처리할 수 있는 상황이라면 CPU는 지금까지의 작업을 스택(Stack) 메모리에 백업을 해둔다.

(5) CPU는 인터럽트 벡터 (Interrupt Vector)를 참조 후 특정 메모리 주소에 접근하여 인터럽트 서비스 루틴을 실행한다.
(6) 인터럽트 서비스 루틴 (ISR) 실행이 끝난 뒤 (4)에서 백업해 둔 작업을 복구하여 실행을 재개한다.

 

[풀이]

(1) 인터럽트 요청 신호:

입출력 장치가 CPU에게 현재 작업을 완료했으니 처리해달라고 요청하는 신호이다.

 

(2) 인터럽트 플래그 (Interrupt Flag):

맨 위 레지스터 관련 포스팅을 본다면 레지스터의 종류 중 CPU 상태의 정보를 담고 있는 플래그 레지스터 (Flag Register)가 있다는 것을 알 수 있다. 플래그 레지스터 관련 자세한 내용은 아래 포스팅에서 정리를 해놨었다.

 

https://yjhdevelopdiary.tistory.com/229

 

[컴퓨터 구조] ALU, 제어 장치

■ 간단한 정의(1) ALU는 계산하는 장치 (2) 제어장치는 제어 신호를 발생시키고 명령어를 해석하는 장치 * 이전에 정보처리 기능사를 공부하면서 정리했었던 '명령어 처리 과정' 글에 덧붙이는

yjhdevelopdiary.tistory.com

 

CPU가 인터럽트를 수용하기 위해선 위 플래그 레지스터 내에서 인터럽트 플래그(IF)1(가능)로 설정되어 있어야 한다.즉, IF가 0일 때는 인터럽트를 수용하지 않으므로 CPU의 작업이 중도에 방해를 받을 일이 없게 된다.

하지만, IF가 0이라고 해서 모든 인터럽트가 거절되는 것은 아니다. 정전이나 하드웨어 고장 같은 크리티컬한 이슈에서는 IF의 설정값과 별개로 CPU가 인터럽트를 받아들이게 되어있다.

 

이와 같이 인터럽트는 인터럽트 플래그(IF)를 통해서 막을 수 있는 인터럽트막을 수 없는 인터럽트로 나뉘게 되는 것을 볼 수 있다.

 

IF로 막을 수 있는 인터럽트 Maskable Interrupt라고 부르고 정전과 같은 막을 수 없는 인터럽트Non-maskable Interrupt라고 부른다.

(3) 인터럽트 서비스 루틴 (ISR; Interrupt Service Routine)

인터럽트를 처리하기 위한 프로그램이다. ISR은 또한 인터럽트 핸들러 (Interrupt Handler)라고도 불려진다.

ISR은 인터럽트가 발생했을 때 인터럽트의 종류에 따라 수행해야하는 각기 다른 명령어들을 내포하고 있다.

예로 키보드가 인터럽트 요청을 보냈을 때 작동해야하는 방식과 마우스가 인터럽트 요청을 보냈을 때 작동해야하는 방식이 다르므로 각기 다른 인터럽트를 어떻게 처리해야하는 지에 대한 정책? 정보?를 내포하고 있는 프로그램을 의미한다.

 

[실행 순서]

(1) 작업 진행 중 인터럽트 발생

(2) 인터럽트 서비스 루틴으로 메모리 주소 점프

(3) 인터럽트 서비스 루틴 실행

(4) 백업 해놨던 기존 작업의 메모리 주소로 점프

(5) 기존 작업 재개

 

위 (2)에서 문득 의문이 생길 것이다. 각기 다른 행동에 따른 수행해야할 명령어가 다르면 ISR 메모리 주소 내에 어디를 참조해야하는 것인가? 쉽게 말해서 키보드 인터럽트 요청에 대한 응답은 0x0001부터 시작되는 명령어를 수행해야하고 마우스 인터럽트 요청에 대한 응답으로는 0x0010부터 시작되는 명령어를 수행해야한다면 이에 대한 플래그는 어디서 받고 있는 것인가?

 

이에 대한 정보는 인터럽트 벡터 (Interrupt Vector)가 내포하고 있다.

(4) 인터럽트 벡터 (Interrupt Vector)

CPU는 수많은 ISR을 구분할 줄 알아야 한다. 인터럽트 벡터는 이러한 인터럽트 서비스 루틴 (ISR)을 식별하기 위한 정보이다. ISR의 시작 주소를 내포하므로 인터럽트 벡터를 안다면, 특정 ISR을 처음부터 실행할 수 있게된다.

 

■ 결론

맨 위에서 명령어 사이클은 크게 인출 사이클 (Fetch Cycle) 실행 사이클 (Execution Cycle) 두 가지로 반복된다고 얘기했다. 더불어 인출 이후 실행하기 전에 데이터를 확인해봤더니 유효주소의 주소를 가져왔다면 간접 사이클(Indirect Cycle)을  통해 메모리 접근을 한 번 더 수행한다는 것 또한 기술했다. 인터럽트 발생 시 실행 사이클 이후 수행하는 여러가지 일련의 작업들이 존재하는 것을 설명하였고 이러한 주기를 인터럽트 사이클 (Interrupt Cycle)이라고 일컫는다.

 

위 내용들을 정리해보자면 명령어 사이클은 크게 아래와 같이 귀결된다고 볼 수 있다.

 

728x90