SPSR는 Saved Program Status Registers의 약자로 CPSR을 백업하는 용도로 사용되는 레지스터입니다. 이어서 Arm 스팩 문서를 보면서 SPSR을 배워봅시다. 

 

 
The Saved Program Status Registers (SPSRs)
The purpose of an SPSR is to record the pre-exception value of the CPSR. On taking an exception, the CPSR is copied to the SPSR of the mode to which the exception is taken. Saving this value means the exception handler can:
 
위 내용은 다음과 같이 요약할 수 있습니다.
 
   * SPSR는 익셉션이 발생하기 전 시점의 CPSR를 저장하려는 목적으로 사용된다.
   * 익셉션을 유발하는 과정에서, 익셉션이 일어나는 시점의 Arm 모드 정보가 담긴 CPSR이 SPSR로 복사된다.
   * 이 값을 활용해 익셉션 핸들러는 다양한 방식으로 처리를 할 수 있다.
 
정리하면 SPSR은 레지스터의 이름과 같이 CPSR를 백업하는 용도로 사용되는 스페셜 레지스터입니다. 그렇다면 SPSR은 CPSR을 언제 백업할까요? 대부분 다음과 같은 상황에서 활용됩니다.
 
    "익셉션이 발생하기 전 시점의 Arm 동작 모드로 복귀하고 싶을 때"
 
익셉션이 발생한 다음에 SPSR 레지스터는 익셉션이 일어난 시점의 Arm 동작 모드를 저장하고 있습니다. 이 정보를 백업해놓고 SPSR 레지스터의 값을 CPSR 레지스터에 다시 로딩하면 이전 Arm 동작 모드로 복귀할 수 있습니다.
 
SPSR 레지스터는 각 Arm 동작 모드 별로 존재하며 이를 'spsr_<mode>'로 표기할 수 있습니다.
r13와 r14와 같이 SPSR는 각 동작 모드 별로 뱅크드됐다고 볼 수 있습니다.
 
한 가지 예를 들어 볼까요? 슈퍼바이저 모드에서 'IRQ 인터럽트'가 발생한 상황입니다. 이 조건에서 SPSR 레지스터가 어떻게 바뀔까요? 다음은 이 동작을 표기한 슈도 코드입니다.
 
[슈퍼바이저 모드] 
1. CPSR.M = 0x13
2. IRQ 인터럽트 익셉션 유발(하드웨어적으로 처리)
   2.1 SPSR_IRQ.M = 0x13
   2.2 CPSR.M = 0x12
 
1번은 현재 Arm의 동작 모드가 슈퍼바이저 모드라는 정보를 나타냅니다. 그런데 슈퍼바이저 모드에서 인터럽트가 유발되면 IRQ 인터럽트 익셉션을 유발하면서 2.1와 2.2에 해당되는 동작을 Arm 코어가 하드웨어적으로 처리합니다. IRQ 인터럽트 익셉션을 유발하면 IRQ 모드로 진입하니 SPSR_IRQ.M 레지스터에 현재 Arm 동작 모드(슈퍼바이저 모드)를 나타내는 0x13을 저장합니다. 
 
[정보]
SPSR_IRQ.M은 SPSR_IRQ 레지스터의 [4:0] 비트를 나타냅니다.
 
 
이번에는 IRQ 모드로 진입한 다음의 세부 동작을 슈도 코드로 알아봅시다. 
 
[IRQ 모드] 
3. IRQ 익셉션 벡터 주소로 분기
   3.1 SPSR_IRQ.M이 담고 있는 값인 0x13(슈퍼바이저 모드)을 백업
   3.2 IRQ 모드에 해당 후속 처리
4. CPSR.M에 백업한 0x13(슈퍼바이저 모드)을 저장
 
[슈퍼바이저 모드] 
5. 슈퍼바이저 모드로 복귀
 
설명한 내용 중에서 3번 동작을 조금 더 자세히 알아봅시다.
 
SPSR_IRQ.M은 IRQ 모드로 진입하기 전의 Arm 동작 모드를 나타내는 비트 정보인 0x13을 저장합니다. 이 값을 다른 레지스터에 백업할 수 있습니다. IRQ 모드에 진입한 후 후속 처리를 3.2에서 한 다음에 4번 동작을 수행하면, IRQ 모드 이전의 Arm 동작 모드로 복귀할 수 있습니다.
 
이번에는 IRQ 모드에서 Undefined Instruction 모드로 진입할 때 SPSR 레지스터가 어떻게 바뀌는지 알아봅시다.
 
[IRQ 모드] 
1. CPSR.M = 0x12
2. Undefined Instruction 익셉션 유발(하드웨어적으로 처리)
   2.1 SPSR_UND.M = 0x12
   2.2 CPSR.M = 0x1b
 
[Undefined Instruction 모드] 
3. Undefined Instruction 익셉션 벡터 주소로 분기
   3.1 SPSR_IRQ.M이 담고 있는 값인 0x12(IRQ 모드)을 백업
   3.2 Undefined Instruction 모드에 해당 후속 처리
4. CPSR.M에 백업한 0x12(IRQ 모드)을 저장해 IRQ 모드로 복귀
 
1번은 현재 Arm의 동작 모드가 IRQ 모드라는 사실을 나타냅니다. 그런데 IRQ 모드에서 Undefined Instruction 익셉션이 유발되면 Arm 코어는 2.1와 2.2에 해당되는 동작을 하드웨어적으로 수행합니다. Undefined Instruction 익셉션을 유발하면 Undefined Instruction 모드로 진입하니 SPSR_IRQ.M 레지스터 현재 Arm 동작 모드인 IRQ 모드를 나타내는 0x12를 저장합니다. 
 
이어서 Undefined Instruction 모드로 진입한 다음의 동작을 나타내는 3번째 슈도 코드를 분석합시다.
 
SPSR_IRQ.M은 Undefined Instruction 모드로 진입하기 전의 Arm 동작 모드를 나타내는 비트 정보를 저장합니다. Undefined Instruction 모드로 진입하기 전에 IRQ 모드였으니 0x12을 저장합니다. 이 값은 다른 레지스터에 백업할 수 있습니다. Undefined Instruction 모드에 진입한 후 3.2와 같이 후속 처리를 하고 나서 4번 동작을 수행하면, Undefined Instruction 모드 이전의 Arm 동작 모드인 IRQ 모드로 복귀할 수 있습니다.
 
이처럼 Arm 동작 모드 별로 SPSR 레지스터가 존재하며, SPSR_<mode>의 특징을 잘 활용해 Arm 동작 모드를 스위칭합니다.
 
< '시스템 소프트웨어 개발을 위한 Arm 아키텍처의 구조와 원리' 저자>
 
* 유튜브 강의 영상
 

 

 

Updated 02.06.2024

 

 

+ Recent posts