이번 문서의 목표: 이 문서를 다 읽으면 ARM 공식 문서(TRM, Programmer’s Model, CMSIS)가 각각 어떤 정보를 담고 있는지 구분하고, 레지스터 표기(R0~R15, 비트필드)와 예외 번호 표기를 정확히 읽어낼 수 있다.
왜 문서 읽는 법부터 배워야 하는가
03편부터는 ARM 아키텍처의 동작 모드, 레지스터, 예외 처리, 주변장치 레지스터 같은 내용이 본격적으로 등장한다. 이 내용들은 예외 없이 표와 비트필드 그림으로 제시되는데, 그 표기법 자체를 모르면 아무리 개념 설명을 잘 읽어도 실제 레지스터 표를 마주치는 순간 막힌다. 마치 악보를 읽는 법을 모르는 채로 음악 이론을 배우는 것과 비슷하다. 이 편은 본론에 들어가기 전에 그 “악보 읽는 법”을 먼저 익히는 자리다.
쉽게 말하면: 이 문서는 앞으로 나올 레지스터 표·비트필드 그림을 술술 읽기 위한 사전 준비 운동이다.
ARM 공식 문서 체계 — 세 가지 문서의 역할 구분
ARM은 특정 회사 이름이 아니라, CPU의 설계도(명령어 집합과 동작 방식의 규격)를 만들어 라이선스로 판매하는 회사이자 그 설계도 자체를 가리키는 이름이다. ARM이 공개하는 문서는 목적에 따라 여러 종류로 나뉘는데, 이 과목에서 자주 마주치는 세 가지를 구분해 두면 앞으로 참고 자료를 스스로 찾아 읽을 때도 헤매지 않는다.
| 문서 | 정식 명칭 | 담고 있는 정보 | 언제 찾아보는가 |
|---|---|---|---|
| Programmer’s Model | 프로그래머 모델 | CPU가 프로그래머(개발자) 입장에서 어떻게 “보이는가” — 레지스터 집합, 동작 모드, 명령어 집합 | 레지스터 이름·동작 모드를 확인할 때 |
| TRM | Technical Reference Manual, 기술 참조 매뉴얼 | 특정 프로세서 코어(예: Cortex-M4)의 상세 동작, 예외 처리, 파이프라인, 코어 주변장치 | 예외 번호·타이밍·코어 세부 동작을 확인할 때 |
| CMSIS | Cortex Microcontroller Software Interface Standard, 코텍스 마이크로컨트롤러 소프트웨어 인터페이스 표준 | 코어 레지스터·주변장치에 접근하는 표준 C 함수·매크로 이름 | 실제 코드에서 레지스터를 다루는 표준 접근 방식을 확인할 때 |
이 세 문서는 서로 대체 관계가 아니라 역할 분담 관계다. Programmer’s Model이 “이 CPU는 이런 부품(레지스터)들로 구성되어 있다”는 설계도라면, TRM은 그 설계도를 실제로 구현한 특정 제품(예: Cortex-M4)이 “구체적으로 몇 사이클 만에 어떻게 동작하는가”를 적은 실측 보고서에 가깝고, CMSIS는 그 하드웨어를 코드에서 건드릴 때 “이런 이름의 함수를 쓰면 된다”고 정해 둔 공통 규칙집이다. 04~06편에서 ARM 아키텍처와 레지스터, 예외 처리를 다룰 때 이 세 문서의 이름이 다시 등장하므로, 지금은 “설계도 – 구현 보고서 – 코드 규칙집”이라는 세 역할만 정확히 구분해 두면 충분하다.
레지스터 이름 표기법 — R0~R15와 별칭
레지스터(register)는 CPU 내부에서 데이터를 아주 빠르게 임시로 저장해 두는 작은 저장 공간이다. ARM 계열 프로세서는 범용 레지스터를 R0부터 R15까지 16개 두는데, 이 표기는 앞으로 계속 나오므로 정확히 읽는 법을 익혀야 한다.
R0~R12: 일반적인 계산·데이터 저장에 자유롭게 쓸 수 있는 범용 레지스터다.R13: SP(Stack Pointer, 스택 포인터)라는 별칭으로도 불리며, 스택(함수 호출 시 임시 데이터를 쌓아 두는 영역)의 맨 위 주소를 가리킨다.R14: LR(Link Register, 링크 레지스터)이라는 별칭으로 불리며, 함수를 호출했을 때 “돌아갈 주소”를 저장한다.R15: PC(Program Counter, 프로그램 카운터)라는 별칭으로 불리며, “다음에 실행할 명령어의 주소”를 담고 있다.
쉽게 말하면: R0~R12는 자유롭게 쓰는 작업 공간, R13(SP)은 스택의 현재 위치 표시, R14(LR)는 돌아갈 곳을 적어 둔 메모지, R15(PC)는 지금 몇 번째 줄을 읽고 있는지 가리키는 손가락이다.
이렇게 번호와 별칭을 함께 쓰는 이유는, 문서에 따라 R13으로 적기도 하고 SP로 적기도 하기 때문이다. 이 과목의 본론에서 두 표기가 섞여 나와도 같은 레지스터를 가리킨다는 것을 바로 알아차려야 한다. SP·LR·PC의 구체적인 동작(함수 호출 시 어떻게 값이 바뀌는지)은 05편(ARM 동작 모드와 레지스터, 예외 처리)에서 실제 예제로 다시 다룬다.
비트필드 표기법 — 레지스터 안의 방 나누기
주변장치를 제어하는 레지스터(예: GPIO 설정 레지스터)는 32비트 전체를 하나의 값으로 쓰지 않고, 몇 개의 비트씩 묶어 각각 다른 의미를 부여하는 경우가 많다. 이렇게 레지스터 하나를 여러 구간으로 쪼개 각 구간에 별도 의미를 주는 것을 비트필드(bit field)라고 부른다.
비트필드는 보통 다음과 같은 표로 표기된다.
| 비트 위치 | 이름 | 의미 |
|---|---|---|
| 31:16 | RESERVED | 예약됨(사용하지 않음) |
| 15:12 | MODE3 | 3번 핀의 동작 모드 |
| 11:8 | MODE2 | 2번 핀의 동작 모드 |
| 7:4 | MODE1 | 1번 핀의 동작 모드 |
| 3:0 | MODE0 | 0번 핀의 동작 모드 |
여기서 31:16처럼 콜론으로 표시된 부분은 “31번 비트부터 16번 비트까지”라는 범위를 뜻한다. 비트는 오른쪽 끝(가장 낮은 자릿값)을 0번으로 세고, 왼쪽으로 갈수록 번호가 커진다. 즉 32비트 레지스터라면 비트 31이 맨 왼쪽(가장 높은 자릿값), 비트 0이 맨 오른쪽(가장 낮은 자릿값)이다.
쉽게 말하면: 32비트 레지스터는 32칸짜리 서랍이고, 비트필드 표는 “몇 번 칸부터 몇 번 칸까지는 이 용도로 쓴다”고 적어 둔 서랍 안내판이다.
예를 들어 위 표에서 2번 핀의 동작 모드를 01(2진수)로 설정하고 싶다면, 레지스터의 비트 8~11 구간에 0001을 써넣어야 한다. 이 값을 10진수로 환산하면 1 × 2⁸ = 256이 되므로, 레지스터 전체에는 이 값을 더해 넣는 방식으로 설정한다. 이런 비트 단위 조작은 08편(GPIO, 폴링과 인터럽트, 타이머·카운터)과 12편(디바이스 드라이버와 임베디드 C)에서 실제 C 코드로 다시 등장한다.
예외 번호 표기법 — IRQ 번호와 벡터 테이블
ARM Cortex-M 계열에서는 인터럽트나 오류 같은 특별한 상황을 예외(exception)라고 통칭하고, 각 예외마다 고유한 번호를 매겨 구분한다. 문서에서 흔히 다음과 같은 방식으로 표기된다.
| 예외 번호 | 이름 | 종류 |
|---|---|---|
| 1 | Reset | 시스템 예외(코어 자체 기능) |
| 2 | NMI | 시스템 예외(Non-Maskable Interrupt, 막을 수 없는 인터럽트) |
| 3 | HardFault | 시스템 예외(심각한 오류) |
| 16 이상 | IRQ0, IRQ1, … | 외부 인터럽트(주변장치가 발생시키는 인터럽트) |
여기서 IRQ(Interrupt ReQuest, 인터럽트 요청)는 타이머, UART, GPIO 같은 주변장치가 “지금 CPU의 처리가 필요하다”고 알리는 신호를 가리키며, 각 주변장치마다 고유한 IRQ 번호가 배정된다. 예외 번호 1~15는 Cortex-M 코어 자체가 갖는 시스템 예외(system exception)에 고정 배정되어 있고, 16번부터는 칩 제조사가 어떤 주변장치를 몇 번 IRQ로 연결할지 정하는 외부 인터럽트 영역이다.
이 번호들이 순서대로 나열된 표를 벡터 테이블(vector table)이라고 부르며, 각 예외가 발생했을 때 “어느 주소의 코드로 점프할 것인가”를 미리 적어 둔 지도 역할을 한다.
쉽게 말하면: 예외 번호는 “무슨 일이 생겼는지”를 구분하는 사건 번호표이고, 벡터 테이블은 “몇 번 사건이 터지면 어디로 뛰어가서 처리할지” 미리 적어 둔 비상 연락망이다.
벡터 테이블과 예외 진입·복귀 과정의 구체적인 동작은 05편에서 예외 우선순위·인터럽트 흐름과 함께 자세히 다룬다.
문서 표기를 코드와 연결 짓는 CMSIS의 역할
지금까지 본 레지스터 이름·비트필드·예외 번호는 어디까지나 문서상의 표기다. 실제 C 코드에서는 이 표기를 그대로 쓰지 않고, CMSIS가 정의한 표준 이름(예: 레지스터 구조체 멤버, NVIC_EnableIRQ() 같은 함수)을 통해 접근한다. 즉 문서의 표기법을 읽을 줄 알아야 CMSIS가 제공하는 함수 이름이 실제로 어느 레지스터·비트를 건드리는지 짐작할 수 있다. CMSIS를 통한 실제 레지스터 접근과 인터럽트 제어 코드는 08편, 12편에서 구체적인 예시로 다시 등장한다.
자주 틀리는 점
- TRM과 Programmer’s Model을 같은 문서로 착각하는 실수: Programmer’s Model은 아키텍처 전반의 설계도이고, TRM은 특정 코어 제품의 세부 구현·타이밍을 담은 문서다. 같은 질문(예: “예외 우선순위는 몇 단계인가”)이라도 정확한 숫자는 TRM에서 확인해야 한다.
- 비트 번호를 왼쪽부터 0으로 세는 실수: 비트는 항상 오른쪽 끝(가장 낮은 자릿값)이 0번이고, 왼쪽으로 갈수록 번호가 커진다.
- IRQ 번호와 예외 번호를 같은 것으로 혼동하는 실수: 예외 번호는 1번부터 시작해 시스템 예외(1~15)와 외부 인터럽트(16 이상)를 모두 포함하는 전체 번호이고, IRQ 번호는 외부 인터럽트만 따로 0번부터 다시 세는 번호다. 즉 “IRQ0”은 예외 번호로는 16번에 해당한다.
핵심 정리
- ARM 공식 문서는 Programmer’s Model(설계도), TRM(특정 코어의 구현 세부), CMSIS(표준 코드 접근 방식)로 역할이 나뉜다.
- 레지스터는 R0~R15로 표기하며, R13은 SP(스택 포인터), R14는 LR(링크 레지스터), R15는 PC(프로그램 카운터)라는 별칭을 갖는다.
- 비트필드 표기
31:16은 “31번 비트부터 16번 비트까지”를 뜻하며, 비트 번호는 오른쪽 끝이 0번이다. - 예외 번호는 1~15가 시스템 예외, 16 이상이 외부 인터럽트(IRQ)이며, 벡터 테이블은 각 예외 번호와 처리 코드 주소를 연결한 표다.
- 이 표기법들은 03편 이후 레지스터 표·비트필드 그림·인터럽트 표에서 계속 반복해 쓰인다.
마무리 복습
참고 자료
- Arm Cortex-M resources — Cortex-M 문서 체계, Programmer’s Model, TRM, 아키텍처 문서의 공식 진입점.
- CMSIS-Core (Cortex-M): Overview — Cortex-M 런타임, 코어 레지스터 접근, 디바이스 주변장치 접근의 표준 인터페이스 개요.