ARM 아키텍처를 이루는 프로그래머 모델 중에서 익셉션은 가장 중요한 기능 중 하나입니다.
운영제체의 커널은 ARM 아키텍처의 익셉션을 활용해 주요 서브 시스템을 구현하기 때문입니다. 또한 실전 프로젝트에서 만나는 다양한 문제를 해결하기 위해서 반드시 알아야 기반 지식입니다.
익셉션은 CPU 아키텍처마다 지원하는 기능으로, x86, MIPS, ARM 아키텍처의 핵심 기능 중 하나입니다. ARM 프로세서에서 익셉션이 어떤 방식으로 동작하는지 소개하기 앞서 익셉션과 관련된 주요 개념을 먼저 소개합니다.
익셉션이란 무엇일까요? 익셉션은 영어로 번역하면, '예외'라는 의미를 지니는데, 소프트웨어를 개발할 때 예외보다는 '예외 처리'란 용어를 자주 사용합니다. '예외(Exception) 처리'란 여러분이 작성한 코드가 정상적으로 동작하지 않는 경우 이를 처리하기 위한 방법이나 루틴을 뜻합니다.
CPU 아키텍처 관점으로 익셉션이란
그렇다면 CPU 아키텍처 관점으로 익셉션은 무엇일까요? CPU 아키텍처의 익셉션은 위에서 말한 ‘예외 처리’의 개념과 크게 다르지 않습니다. 이번에는 CPU 아키텍처 관점으로 익셉션에 대해서 알아 봅시다.
x86, MIPS, RICS-V, 그리고 이 책에서 다루는 ARM(ARMv7, ARMv8) 아키텍처 기반의 CPU는 각각 머신에 맞게 빌드된 기계어를 실행합니다. 해당 CPU 아키텍처를 설계한 개발자는 “각 CPU 코어에서 기계어를 실행하면 예측한대로 동작할 것이다”라고 예상했을 겁니다. 하지만 CPU 코어가 기계어를 제대로 실행하지 못하는 상황을 확인하게 되는데 대표적인 사례는 다음과 같습니다.
❑ 기계어를 메모리 주소에서 가져오지 못한다.
❑ 기계어를 CPU 코어가 해석할 수 없다.
❑ CPU 코어가 접근할 수 없는 메모리 주소에 엑세스하려고 한다.
여러분이 작성한 코드가 정상적으로 동작하지 않는 경우 이를 처리하기 위해 익셉션 처리를 하듯이, “CPU 코어에서도 기계어를 정상적으로 실행하지 못한 상황에서 이를 처리하는 방식이 익셉션”입니다.
그렇다면 CPU 아키텍처 관점으로 기계어를 정상적으로 실행하지 못한 상황에서 이를 어떻게 처리할까요? 각 아키텍처마다 익셉션의 세부 동작 방식이 다르기는 하나, 공통으로 적용되는 개념이 있습니다. 바로 "익셉션이 발생하면 익셉션의 종류 별로 지정된 주소로 프로그램 카운터가 바뀐다"라는 점입니다.
CPU 아키텍처마다 정의하는 익셉션의 세부 타입과 세세한 처리 방식은 다르나, 위에서 설명한 동작 원리는 기본적으로 같습니다. 만약 ARMv7 아키텍처에서 익셉션의 동작 원리를 제대로 파악하면 다른 CPU 아키텍처에서 익셉션이 동작하는 방식은 그리 어렵지 않게 파악할 수 있습니다.
ARM 아키텍처 관점으로 익셉션이란
다른 CPU 아키텍처와 마찬가지로 ARM 아키텍처에서도 익셉션을 지원합니다.
ARM 아키텍처에서 익셉션의 기본 동작 원리는 무엇일까요? 쉽게 설명드리면, ARM 프로세서는 익셉션이 발생하면 익셉션을 처리하는 특정 모드로 진입합니다. "익셉션을 처리하는 특정 모드"에서는 다음과 같은 동작을 수행합니다.
❑ 익셉션을 유발한 다양한 정보를 레지스터를 업데이트한다.
❑ 익셉션 종류별로 이미 정해 놓은 주소로 브랜치한다.
위 내용이 ARMv7과 ARMv8 아키텍처에서 공통으로 익셉션이 처리되는 방식입니다.
ARM 스팩 문서에서 익셉션 확인하기
ARM 프로세서를 공부하는 방법 중 하나는 ARM사에서 작성해 배포한 스팩 문서를 분석하는 것입니다. 이번에는 ARM 스팩 문서에서 익셉션을 어떻게 설명하는지 소개합니다.
출처: ARM® Architecture Reference Manual(ARMv7-A and ARMv7-R edition)
B1.8 Exception handling
An exception causes the processor to suspend program execution to handle an event, such as an externally generated interrupt or an attempt to execute an undefined instruction. Exceptions can be generated by internal and external sources.
위 내용은 다음과 같이 해석할 수 있습니다.
❑ 익셉션은 프로세서가 “외부에서 발생한 인터럽트나 정의돼 있지 않은 명령어를 실행하려는
시도”와 같은 이벤트를 처리하기 위해 프로세스의 실행을 멈춘다.
이번에는 같은 스팩 문서에서 다른 내용을 확인해 보겠습니다.
출처: ARM® Architecture Reference Manual(ARMv7-A and ARMv7-R edition)
B1.8.1 Exception vectors and the exception base address
When an exception is taken, processor execution is forced to an address that corresponds to the type of exception.This address is called the exception vector for that exception.
위 문장은 다음과 같이 해석할 수 있습니다.
❑ 익셉션이 발생하면, 프로세서는 익셉션의 종류에 따른 주소로 실행된다.
이 주소는 익셉션에 대한 익셉션 벡터라고 부른다.
아쉽지만 익셉션을 한 문장으로 명확히 정의내리지 않습니다. 위에서 명시된 스팩 문서의 내용을 종합해 조금 더 명확하게 다음과 같이 익셉션을 해석해 보겠습니다.
❑ 익셉션은 프로세스의 실행 흐름을 바꾸는 소스로, 익셉션이 발생하면 익셉션의 종류 별로
지정된 주소로 프로그램 카운터(레지스터)를 브랜치한다.
위 문장에서 프로세스는 ARM 프로세서와 다른 개념으로, 운영체제에서 설명하는 프로세스를 의미합니다. 즉, 여러분이 작성한 코드를 실행하는 주체를 의미합니다.
익셉션 벡터 테이블이란
위에서 "익셉션이 발생하면 익셉션의 종류 별로 지정된 주소로 프로그램 카운터가 브랜치된다"라고 언급했습니다. 익셉션의 종류 별로 지정된 주소로 ARM 프로세서의 프로그램 카운터가 바뀌는데, 이를 익셉션 벡터라고 부릅니다. 이런 익셉션 벡터를 모아놓은 주소 테이블을 익셉션 벡터 테이블이라고 합니다.
다음 ARMv7 아키텍처의 익셉션 벡터 테이블을 소개합니다.

표 7.1 ARMv7 아키텍처의 익셉션 벡터 테이블
표 7.1은 ARMv7 아키텍처의 익셉션 벡터 테이블입니다. 왼쪽 행은 익셉션 벡터, 오른쪽 행은 익셉션의 종류가 보이는데 익셉션 벡터의 주소는 익셉션의 종류에 따라 다르다는 점을 확인할 수 있습니다.
익셉션 벡터의 주소는 "익셉션 벡터 베이스 주소"에서 익셉션 종류 별로 명시된 오프셋 주소를 더해 계산합니다. 만약 "익셉션 벡터 베이스 주소"가 0xffff0000인데, '데이터 어보트'란 익셉션이 발생하면 ARM 프로세서의 프로그램 카운터는 다음 공식에 따라 0xffff0010 주소로 브랜치합니다.
❑ 0xffff0000 + 0x10 = 익셉션 벡터 베이스 주소 + 오프셋 주소
한 가지 기억할 사실은 ARMv7 아키텍처와 ARMv8 아키텍처 별로 정의된 익셉션의 종류가 약간 다르다는 겁니다. 하지만 주요 개념은 거의 비슷하니, ARMv7 아키텍처의 익셉션의 개념을 이해하면 ARMv8의 익셉션의 동작 원리도 쉽게 파악할 수 있습니다.
---
"이 포스팅이 유익하다고 생각되시면 공감 혹은 댓글로 응원해주시면 감사하겠습니다.
"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!"
Thanks,
Guillermo Austin Kim(austindh.kim@gmail.com)
---
Written by <디버깅을 통해 배우는 리눅스 커널의 구조와 원리> 저자

최근 덧글