CPU 아키텍처를 배울 때 가장 먼저 어셈블리 명령어와 레지스터의 용법을 파악합니다. 어셈블리 명령어는 레지스터로 구성돼 있어 어셈블리 명령어를 익히려면 레지스터의 용법을 알아야 합니다. 그렇다면 Arm 아키텍처는 같은 레지스터를 사용할까요? 그렇지 않습니다. Armv7와 Armv8 아키텍처 별로 각각 레지스터를 정의합니다.
 
이번 포스트에서 Armv7 아키텍처에서 정의된 레지스터를 다룹니다. 먼저 범용 레지스터를 설명하겠습니다.
 
범용 레지스터 
 
레지스터란 무엇일까요? 레지스터는 메모리 계층 구조 관점으로 설명할 수 있습니다. Arm 코어가 사용하는 데이터를 저장하는 임시 저장 공간을 레지스터라고 합니다. 그런데 소프트웨어 관점으로는 Armv7 아키텍처에서 레지스터는 범용 레지스터와 CP15 레지스터로 분류될 수 있습니다. 이 중에서 먼저 범용 레지스터를 알아봅시다. 
 
Arm 스팩 문서에서 범용 레지스터 확인하기
 
누군가 레지스터라고 말하면 ‘범용 레지스터’를 떠올리는 분이 많습니다. 시스템 소프트웨어 개발자들이 가장 먼저 접하는 레지스터가 범용 레지스터이기도 합니다.
 
다음은 Arm 스팩 문서에서 범용 레지스터를 설명한 내용입니다.
 
<출처: DEN0013D_cortex_a_series_PG.pdf>
3.1 Registers
The ARM architecture provides sixteen 32-bit general purpose registers (R0-R15) for software use. Fifteen of them (R0-R14) can be used for general purpose data storage, while R15 is the program counter whose value is altered as the core executes instructions. An explicit write to R15 by software will alter program flow. Software can also access the CPSR, and a saved copy of the CPSR from the previously executed mode, called the Saved Program Status Register
(SPSR). 
 
범용 레지스터를 포함한 전반적인 레지스터를 명확하게 설명하는 내용입니다. 스팩의 내용을 요약해 볼까요?
 
   * Arm 아키텍처는 32-비트로 구성된 범용 레지스터(R0-R15)를 제공한다. 
     (이 레지스터는 소프트웨어에서 사용된다.)
   * R0-R14 레지스터는 데이터를 처리하는 범용 용도로 사용되고, R15는 Arm 코어가 실행하는 명령어(Instruction)의 주소를 저장하는 프로그램 카운터이다.
   * R15를 바꾸면 프로그램의 실행 흐름이 바뀔 수 있다.
   * CPSR 레지스터는 프로세서의 실행 상태를 저장하는데 CPSR 레지스터의 복사본이 SPSR 레지스터이다. SPSR 레지스터는 이전에 Arm 동작 모드의 프로세서 상태 정보를 저장한다.
 
Arm 스팩 문서는 포괄적인 내용을 담고 있어 용어나 문구를 바로 이해하기 어렵습니다. 이어지는 절에서 스팩 문서에서 조금 보충해야 할 내용을 설명합니다.
 
R0~R15 레지스터의 역할
 
Armv7 아키텍처에서 정의된 범용 레지스터를 알려면 R0~R15 레지스터의 역할을 파악할 필요가 있습니다. 다음은 Armv7 코어에서 사용되는 레지스터 세트를 나타낸 그림입니다.
 
 
그림 2.1 Arm 모드 별로 사용되는 레지스터의 목록
<출처: DDI0406C_C_Arm_architecture_reference_manual.pdf>
 
위 그림에서 가장 윗 부분에 보이는 User~FIQ는 Armv7에서 지원하는 Arm 동작 모드를 나타냅니다. 이 내용으로 Arm 동작 모드 별로 사용되는 레지스터가 있다는 사실을 추정할 수 있습니다.
 
가장 왼쪽 행에 있는 R0부터 PC까지 흰색 배경으로 표시된 부분을 보면, 이는 범용으로 사용되는 레지스터 세트입니다. 어떤 Arm의 동작 모드(Operation Mode)에서도 사용할 수 있는 레지스터를 뜻합니다.
 
그런데 회색 음영으로 표시된 레지스터들은 특정 동작 모드에서만 접근할 수 있는 레지스터입니다. 다음 표에서 Supervisor 모드, IRQ 모드 그리고 FIQ모드에서 엑세스할 수 있는 레지스터를 확인할 수 있습니다.
 
 
표 2.1 각 모드별 접근 가능한 레지스터의 목록
 
위 표에서 명시된 SP_<mode>, LR_<mode>, SPSR_<mode> 레지스터들은 지정된 모드에서만 접근되는 레지스터인데, 이런 레지스터는 뱅크드됐다라고도 합니다.
 
이어서 R0-R14 레지스터를 알아봅시다. R0-R14 레지스터는 데이터를 처리할 때 입력이나 출력값을 저장할 때 사용됩니다. 데이터를 처리하는 연산은 다음과 같습니다.
 
     “산술 연산, 메모리 접근”
 
R13은 스택 포인터(Stack Pointer) 레지스터로 사용되며 현재 프로세스의 스택을 어디까지 사용했는지를 가리킵니다. R13 레지스터는 프로세스가 가장 마지막에 사용된 스택의 위치를 저장하므로 프로세스의 실행 흐름을 알 수 있는 매우 중요한 정보입니다.
 
R14는 링크(Link) 레지스터로 사용되며 Arm 코어가 서브 루틴으로 분기할 때 복귀할 주소를 저장합니다. 쉽게 설명하면 Arm 코어는 어딘가(주소, 함수)로 브랜치를 할 때 어디서 브랜치를 했는지를 R14 레지스터에 업데이트합니다. 그래서 디버깅을 할 때 가장 많이 참고하는 레지스터가 R14입니다.
 
R15는 프로그램 카운터(Program Counter)로 사용되며 Arm 코어가 실행 중인 명령어(Instruction)의 주소를 저장하는 레지스터입니다. Arm 코어가 명령어를 읽을 때 사용되는 가장 중요한 레지스터인 PC는 Arm 코어가 읽어 올 명령어가 있는 주소를 담고 있습니다. 프로그램 카운터를 변경하면 프로그램의 실행 흐름이 바뀝니다.
 
[정보]
x86 아키텍처에서 Armv7 아키텍처의 PC와 같은 용도로 사용되는 레지스터를 IP(Instruction Pointer) 레지스터라고 합니다. x86 아키텍처는 레지스터의 이름을 잘 지은 듯 합니다. Instruction Pointer라는 명칭만 봐도 명령어가 위치한 주소를 가리킨다고 떠오르지 않나요?  
 
 
그런데 여러분이 TRACE32나 GDB와 같은 디버깅 툴을 사용하면 바로 다음과 같은 사실을 확인할 수 있습니다.
 
    "Arm 코어는 PC가 가리키는 주소에 있는 명령어를 읽은 후, PC를 4바이트로 증가시킨다."
 
PC가 명령어를 읽은 후에 4바이트 씩 증가하는 이유는 무엇일까요? Arm 아키텍처에서 사용되는 명령어의 사이즈는 4바이트이기 때문입니다.

 

< '시스템 소프트웨어 개발을 위한 Arm 아키텍처의 구조와 원리' 저자>
 
 
* 강의 영상
 
 
 

 

Updated 02.06.2024

+ Recent posts