테마
CPU의 동작 2
CPU의 동작에서 본 명령어 사이클(instruction cycle)을 잠시 끊고 급한 일을 먼저 처리하게 하는 인터럽트(interrupt)를 이어서 다룬다. 인터럽트를 누가 일으키는지에 따라 종류를 나누고, CPU가 하던 일을 저장했다가 되돌아오는 순서를 본다. 운영체제가 입출력 완료를 알아채고 CPU를 여러 프로그램에 나눠 주는 일이 모두 이 인터럽트 위에서 돌아간다.
인터럽트
인터럽트는 CPU가 하던 일을 잠시 멈추고 더 급한 일을 먼저 처리하게 하는 신호다. 인터럽트가 없으면 CPU는 키보드가 눌렸는지, 디스크 읽기가 끝났는지를 계속 물어보며 기다려야 한다. 인터럽트가 있으면 CPU는 자기 일을 하다가 알림이 올 때만 반응하면 된다.
인터럽트는 원인에 따라 세 가지로 나눈다. 분류와 용어는 교재·CPU 제조사마다 조금씩 다르지만 큰 틀은 같다.
| 종류 | 누가 일으키나 | 언제 오나 | 예 | 정보처리기사 분류 |
|---|---|---|---|---|
| 하드웨어 인터럽트 | CPU 바깥의 장치 | 아무 때나(비동기) | 디스크 읽기 완료, 키 입력, 타이머 | 외부 인터럽트 |
| 예외(exception) | 실행 중인 명령어 | 그 명령어를 실행할 때(동기) | 0으로 나누기, 잘못된 메모리 접근, 페이지 폴트(page fault) | 내부 인터럽트 |
| 소프트웨어 인터럽트 | 프로그램이 일부러 | 그 명령어를 실행할 때 | 시스템 콜(system call) | 소프트웨어 인터럽트 |
페이지 폴트는 필요한 데이터가 아직 메모리에 없을 때 생기는 예외다. 시스템 콜은 응용 프로그램이 트랩(trap) 명령어로 일부러 커널(kernel)에 들어가 일을 부탁하는 것이다. 요즘 PC·서버 CPU 대부분이 쓰는 x86-64는 이 용도로 전용 syscall 명령어를 쓰지만, 일부러 커널로 넘어간다는 원리가 같아 교재는 소프트웨어 인터럽트로 분류한다.
하드웨어 인터럽트가 오면 CPU는 대략 다음 순서로 처리한다.
다이어그램 로딩…
CPU는 먼저 실행 중이던 명령어를 마친다. 그다음 다음에 실행할 위치를 담은 프로그램 카운터(program counter)와 직전 연산 결과의 상태를 담은 플래그(flag)를 스택(stack)에 저장한다. 이렇게 저장해야 서비스 루틴이 끝난 뒤 돌아올 자리를 잃지 않는다.
인터럽트 벡터(interrupt vector)는 인터럽트 번호마다 처리 루틴의 주소를 적어 둔 표다. CPU는 이 표에서 찾은 주소의 인터럽트 서비스 루틴(interrupt service routine)으로 점프한다. 이 루틴은 장치를 직접 다루는 커널 코드이므로, CPU는 점프하면서 커널 모드(kernel mode)로 바뀐다.
하드웨어 인터럽트는 지금 명령어를 마친 뒤 처리하지만, 예외는 이 첫 단계가 다르다. 페이지 폴트처럼 명령어가 끝나지 못해 생긴 예외는 그 명령어를 마치지 않은 채 처리 루틴으로 가고, 저장되는 주소도 그 명령어를 가리킨다. 운영체제가 원인을 해결하고 돌아오면 CPU는 그 명령어를 처음부터 다시 실행한다.
일부 인터럽트는 잠시 막아 둘 수 있는데, 이를 인터럽트 마스킹(interrupt masking)이라 한다. 커널이 꼭 끊기지 않아야 할 짧은 구간을 처리할 때 쓴다. 하드웨어 고장처럼 반드시 알려야 하는 일은 NMI(Non-Maskable Interrupt, 막을 수 없는 인터럽트)로 따로 둔다. 운영체제는 타이머 인터럽트를 이용해, 한 프로그램이 CPU를 독점하지 않도록 정해진 시간마다 CPU를 되찾아 다른 프로그램에 넘긴다. 이 과정은 프로세스와 스레드의 문맥 교환(context switch)으로 이어진다.
면접 포인트
- "인터럽트가 왜 필요한가요?" → 없으면 CPU가 장치를 계속 확인하며 기다려야 한다. 알림이 올 때만 반응하면 된다.
- "인터럽트 처리 과정은?" → 현재 명령어 마침 → 상태 저장 → 인터럽트 벡터로 서비스 루틴 실행 → 복원·재개. 페이지 폴트 같은 예외는 그 명령어를 다시 실행.
- 하드웨어 인터럽트는 비동기, 예외는 명령어가 원인(동기), 시스템 콜은 소프트웨어 인터럽트.
