인터럽트와 예외

프로세서는 일반적으로 프로그램의 명령을 순서대로 실행한다. 그러나 입출력 장치의 요청이나 오류처럼 즉시 처리해야 하는 사건이 발생하면 현재 실행 흐름을 잠시 중단하고, 운영체제나 펌웨어에 등록된 처리 루틴으로 제어를 넘긴다. 이러한 제어 이전을 포괄적으로 **예외(exception)**라고 한다.

CSAPP에서 인터럽트는 예외의 한 종류로 분류된다. 인터럽트와 다른 예외의 가장 큰 차이는 사건이 발생하는 시점이다.

  • 인터럽트(interrupt): 타이머나 입출력 장치처럼 프로세서 외부에서 발생하는 비동기 사건이다.
  • 트랩(trap): 시스템 콜처럼 프로그램이 의도적으로 발생시키는 동기 예외다.
  • 결함(fault): 페이지 폴트처럼 복구할 수 있는 오류다. 처리 후 문제가 된 명령을 다시 실행할 수 있다.
  • 중단(abort): 하드웨어 오류처럼 복구하기 어려운 심각한 오류다. 일반적으로 현재 프로그램을 계속 실행할 수 없다.

예외가 발생하면 시스템은 대체로 다음 순서로 처리한다.

  1. 현재 실행 상태를 나타내는 레지스터와 프로그램 카운터 등의 **컨텍스트(context)**를 저장한다.
  2. 예외 벡터 테이블을 참조해 해당 예외의 핸들러로 제어를 넘긴다.
  3. 핸들러가 원인을 처리한 뒤, 실행을 재개할지 또는 프로그램을 종료할지 결정한다.
  4. 실행을 재개할 수 있다면 저장해 둔 컨텍스트를 복원하고 원래 제어 흐름으로 돌아간다.

NVIC (ARM Cortex-M)

**NVIC(Nested Vectored Interrupt Controller)**는 ARM Cortex-M 프로세서에 포함된 인터럽트 컨트롤러다. 따라서 모든 컴퓨터가 NVIC를 사용하는 것은 아니며, Cortex-M 환경에서 발생하는 시스템 예외와 외부 인터럽트를 관리하는 장치라고 이해해야 한다.

NVIC의 주요 특징은 다음과 같다.

  • 예외 번호를 바탕으로 벡터 테이블의 핸들러를 선택한다.
  • 인터럽트별 우선순위를 설정할 수 있다.
  • 우선순위가 높은 인터럽트가 낮은 인터럽트의 처리를 선점하는 중첩 인터럽트를 지원한다.
  • 예외 진입 시 필요한 일부 레지스터를 하드웨어가 자동으로 스택에 저장한다.
  • 인터럽트 처리 지연 시간이 짧고 비교적 예측 가능하도록 설계되어 있다.