명령어 사이클과 인터럽트

.·2023년 12월 28일

computer-architecture

목록 보기
4/10

명령어 사이클
: 프로그램 속 명령어들은 일정한 주기가 반복되며 실행
이 주기를 명령어 사이클이라고 함

메모리에 저장된 명령어를 실행하려면 인출을 해야한다.
이러한 인출하는 주기를 인출사이클이라고 한다.

메모리에서 인출했으면 실행을 해야한다.
실행하는 주기를 실행 사이클이라고 한다.

일반적으로 CPU는 인출-실행-인출-실행 - ... 인출 사이클과 실행 사이클이 반복되면서 실행된다.
이러한 사이클이 명령어 사이클의 일부라고 우선 생각하면 된다.

그런데 CPU로 명령어를 가지고 와도 바로 실행이 불가능한 경우도 있다.
즉 추가적으로 메모리에 접근해야하는 경우도 있다.

따라서 추가적인 메모리에 접근해야하는 경우도 있기 때문에 아래 그림과 같이 인출-실행 사이클에 간접 실행 사이클도 추가된다.

일반적으로 인터럽트라는 개념이 없다면 CPU 는 인출-실행-간접 사이클을 바탕 실행된다.


인터럽트

인터럽트는 CPU가 인출-실행-간접 사이클 주기로 실행되고 있는데 이 흐름을 끊어버린다.
인터럽트는 CPU가 얼른 처리해야할 다른 작업이 생겼을 때 발생한다.

인터럽트를 예시를 들면 우리가 자주하는 키보드 인터럽트가 있다.

인터럽트의 종류

  • 동기 인터럽트 (예외)
  • 비동기 인터럽트(하드웨어 인터럽트)

동기 인터럽트

동기 인터럽트 종류는

  • 폴트
  • 트랩
  • 중단
  • 소프트웨어 인터럽트

가 있다.

비동기 인터럽트

  • 주로 입출력장치에 의해 발생
  • 알림(세탁기 완료 알림, 전자레인지 조리 알림)과 같은 역할

하드웨어 인터럽트에 대해 더 자세히 알아보면

하드웨어 인터럽트는 입출력 작업 도중에도 효율적으로 명령어를 처리하기 위해 하드웨어 인터럽트 사용한다.
입출력 장치는 CPU에 비해 느리다.
만약 인터럽트가 없다면 CPU는 프린터 완료 여부를 확인하기 위해 주기적으로 확인해야한다.


인터럽트의 처리 순서는

  1. 입출력장치는 CPU에 인터럽트 요청 신호를 보낸다.
  2. CPU는 실행 사이클이 끝나고 명령어를 인출하기 전 항상 인터럽트 여부를 확인한다.
  3. CPU는 인터럽트 요청을 확인하고 플래그 레지스터에 있는 인터럽트 플래그를 통해 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부를 확인한다.
  4. 인터럽트를 받아들일 수 있다면 CPU는 지금까지의 작업을 백업한다.
  5. CPU는 인터럽트 벡터를 참조하여 인터럽트 서비스 루틴을 실행한다.
  6. 인터럽트 서비스 루틴 실행이 끝나면 4번에서 백업해 둔 작업을 복구하여 실행을 재개한다.

인터럽트 요청 신호

인터럽트 플래그

  • CPU는 실행 사이클이 끝나고 명령어를 인출하기 전 항상 플래그 레지스터에 있는 인터럽트 플래그를 를 확인한다.
  • 인터럽트 플래그에서는 "현재 인터럽트를 받아들일 수 있다" 또는 "현재 인터럽트를 받아들일 수 없다" 이런씩으로 0 과 1 로 표기가 된다.
  • 만약 인터럽트 플래그가 인터럽트를 받아들일 수 없는 상태라면 CPU 에 인터럽트 요청이 와도 처리하지 않는다.
    (하지만 모든 인터럽트를 인터럽트 플래그로 막을 수 있는 건 아니다. (e.g. 강제종료, ..) , 이렇게 막을 수 없는 인터럽트를 non maskable interrupt 라고 한다.)

인터럽트 서비스 루틴

CPU 가 인터럽트를 받아들이기로 했다면 언터럽트 서비스 루틴 이라는 프로그램을 실행한다.

  • 인터럽트 서비스 루틴이란, 인터럽트가 발생했을 때 해당 인터럽트를 어떻게 처리하기 위한 프로그램
    • "키보드가 인터럽트 요청을 보내면 이렇게 행동해야한다" -> 인터럽트 벡터를 확인하고 JUMP 해서 인터럽트 서비스 루틴 A 을 실행 다시 실행중인 프로그램으로 되돌아온다
    • "마우스가 인터럽트 요청을 보내면 이렇게 행동해야한다" -> 인터럽트 벡터를 확인하고 JUMP 해서 인터럽트 서비스 루틴 B 을 실행 후 다시 실행중인 프로그램으로 되돌아온다
    • ...


인터럽트 벡터 : 각각 인터럽트를 구분하기 위한 정보


서비스가 인터럽트를 받아 들일 때 인터럽트 서비스 루틴을 실행해야하는데, 인터럽트 벡터안에는 해당 입출력 장치의 인터럽트 서비스 루틴의 시작 주소가 담겨 있다.
즉 cpu 에 인터럽트를 보낼 때 인터럽트 벡터 또한 데이터 버스로 보낸다.

즉 cpu 가 인터럽트를 처리한다는 말은

=== 인터럽트 서비스 루틴을 실행하고, 본래 수행하던 작업으로 다시 되돌아온다.
(+ 그리고 인터럽트의 시작 주소는 인터럽트 벡터를 통해 알 수 있다)

인터럽트가 발생해서 인터럽트 서비스 루틴이 실행되면 어떻게 다시 실행중인 프로그램에 되돌아 갈까 ?

  • 1500 번지의 프로그램이 실행되고 있는 도중 만약 인터럽트가 들어왔다면 CPU 에 있는 레지스터들의 데이터들은 그냥 삭제하고 인터럽트 서비스 루틴을 실행하면 안된다.
  • 지금까지 했던 작업을들 인터럽트 서비스 루틴이 실행이 끝나면 다시 되돌아와서 해야하기 때문에 지금까지 했던 작업(레지스터들에 있는 데이터)들을 백업 시켜둬야한다.

  • 즉 인터럽트가 들어오면 1500번지에서 실행중인 프로그램이 지금까지 작업내역(레지스터에 담긴 데이터)들을 Stack 영역에 백업해두고, 프로그램 카운터를 인터럽트 서비스 루틴 메모리 주소인 10번지로 변경해준다.
  • 인터럽트 서비스 루틴이 실행되면 인터럽트 서비스 루틴을 실행하기 위한 데이터들이 레지스터에 담기게 되고 , 인터럽트 서비스 루틴의 실행이 끝나면 스택에 백업해둔 정보들을 복구해서 실행시키면 된다.

명령어 사이클

지금까지 나온 개념들을 모두 추가한
인출-실행-간접-인터럽트 사이클은 다음과 같다.


Reference

profile
.

0개의 댓글