이어서 X30 레지스터를 스펙 문서 분석을 통해 알아봅시다.

출처: ARM® Cortex®-A Series Programmer's Guide for ARMv8-A https://developer.arm.com/documentation/den0024/latest/ 
6.4 Flow control
...
Calls to subroutines, where it is necessary for the return address to be stored in the link register (X30), use the BL instruction. This does not have a conditional version. BL behaves as a B instruction with the additional effect of storing the return address, which is the address of the instruction after the BL, in register X30.

X30 레지스터를 설명한 내용인데, 요약하면 다음과 같습니다.

 X30은 BL 명령어를 실행해 주소나 함수로 분기했을 때 서브루틴에서 복귀할 주소를 저장하는 레지스터다.  

 

---

[중요] Armv7의 R14_<mode> 레지스터와 Armv8의 X30 레지스터

Armv7 아키텍처에서는 R14가 각 동작 모드별로 존재했습니다. R14는 서브루틴(함수 호출)을 호출할 때 복귀할 주소뿐만 아니라 익셉션이 유발된 후 복귀할 주소를 저장했습니다.

그런데 Armv8 아키텍처에서는 익셉션이 발생한 후 복귀할 주소를 저장하는 ELR_ELx(Exception Link Register)를 익셉션 레벨별로 정의합니다. 그래서 Armv8 아키텍처에서 X30은 익셉션 레벨별로 존재하지 않습니다.
---

이처럼 SP와 X30 레지스터는 Armv8 아키텍처에서 정의된 다른 범용 레지스터와 달리 서브루틴으로 분기하기 위해 사용됩니다.

이번 절에서 소개한 SP_ELn과 X30 레지스터를 표로 정리해 봅시다.


표 13.1 SP_ELn과 X30 레지스터의 특징
  
어셈블리 명령어를 분석할 때 SP_ELn과 X30 레지스터를 보면 그 역할과 기능이 잘 떠올랐으면 좋겠습니다.

 <강의 영상>

 

 

[Arm프로세서] Armv8 - SP_ELn과 X30 레지스터란?
 
Armv8 아키텍처에서 정의된 레지스터 중 SP_ELn과 X30 레지스터는 AAPCS와 연관된 핵심 레지스터입니다. 전체 레지스터 목록 중에서 SP_ELn과 X30 레지스터를 먼저 소개하겠습니다.

전체 레지스터 목록 중 SP_ELn과 X30 레지스터

다음 그림을 보면서 Armv8 아키텍처에서 정의된 레지스터 중 AAPCS와 연관된 레지스터 목록을 알아봅시다.


 
그림 13.1 Armv8 아키텍처의 레지스터 목록 중 AAPCS와 연관된 레지스터

위 그림은 Armv8 아키텍처에서 정의된 레지스터 목록입니다. 그림에서 빗금으로 표기된 박스를 보겠습니다.

SP_EL1은 EL1(익셉션 레벨1)에서 실행되는 SP 레지스터, SP_EL0는 EL0(익셉션 레벨0)에서 실행되는 SP 레지스터를 의미합니다. 또한 하이퍼바이저가 실행되는 EL2에서 실행되는 SP 레지스터는 SP_EL2로 표기합니다.

---
[정보] SP 레지스터와 SP_ELn 레지스터의 상관관계

Armv8 아키텍처에서는 SP 레지스터를 SP_ELn으로도 표기합니다. 그렇다면 다음과 같은 명령어는 어떻게 해석해야 할까요?

SUB SP, SP, #4

Armv8 아키텍처의 어셈블리 명령어에서 SP가 보이면 어셈블리 명령어를 실행하는 익셉션 레벨을 기준으로 해석하면 됩니다. 만약 위 명령어를 실행하는 익셉션 레벨이 EL1이면 SP_EL1, EL2이면 SP_EL2를 의미합니다.

예를 들어, 운영체제 커널은 EL1에서 실행되므로 커널 공간에 있는 프로세스의 SP 레지스터는 SP_EL1에서 확인할 수 있습니다. 하이퍼바이저는 EL2에서 실행되므로 하이퍼바이저에서 실행되는 프로세스의 SP 레지스터는 SP_EL2에서 확인할 수 있습니다. 
---

X30 레지스터는 링크 레지스터를 뜻하며, 서브루틴을 호출한 다음에 복귀할 주소를 저장합니다. Armv7 아키텍처의 링크 레지스터인 R14와 같은 기능입니다.

SP_ELn 아랫 부분에 표기된 레지스터를 보겠습니다. 프로세서의 상태를 저장하는 SPSR(Saved Program Status Register) 레지스터와 ELR(Exception Link Register) 레지스터가 있습니다. 이 레지스터도 익셉션 레벨별로 정의돼 있어 SPSR_ELx, ELR_ELx로 표기합니다. 이 레지스터는 AAPCS와는 직접적인 연관은 없습니다. 익셉션이 유발돼 익셉션을 처리한 다음에 이전 익셉션 레벨로 복귀하기 위한 용도로 쓰입니다. 

Arm 스펙 문서에서 본 SP 레지스터

이번에는 Arm 스펙 문서를 보면서 SP와 X30 레지스터에 대해 더 자세히 알아봅시다. 먼저 SP 레지스터를 살펴봅시다.  

출처: ARM® Cortex®-A Series Programmer's Guide for ARMv8-A https://developer.arm.com/documentation/den0024/latest/
4.1.2 Stack pointer

In the ARMv8 architecture, the choice of stack pointer to use is separated to some extent from the Exception level. By default, taking an exception selects the stack pointer for the target Exception level, SP_ELn. 

For example, taking an exception to EL1 selects SP_EL1. Each Exception level has its own stack pointer, SP_EL0, SP_EL1, SP_EL2, and SP_EL3.

위 스펙 내용에서 중요한 부분은 다음과 같이 정리할 수 있습니다.

 익셉션 레벨별로 스택이 존재하는데, 이 스택 주소를 저장하는 SP_ELn 레지스터가 있다.
 SP_EL0, SP_EL1, SP_EL2, SP_EL3와 같은 스택 포인터 레지스터가 존재한다.

여기서 언급된 스택은 프로세스가 사용하는 스택을 의미합니다. Armv8에서 정의된 SP_ELn 레지스터도 프로세스의 스택 주소 구간 내 특정 주소로 업데이트됩니다. 
 

<강의 영상>

 

Armv8 아키텍처의 AAPCS를 다루기에 앞서 Armv7에서 정의된 AAPCS의 주요 내용을 요약하면 다음과 같습니다.

 서브루틴을 호출하면 프로세스의 스택 공간에 레지스터를 푸시한다.
 'BL [주소]' 명령어를 실행해 서브루틴으로 분기하면 Arm 코어는 링크 레지스터인 R14에 복귀할 주소를 업데이트한다.
 서브루틴을 호출할 때 전달되는 인자는 R0 ~ R3 레지스터에 저장된다.
 함수의 리턴값은 R0 레지스터에 저장된다.

위에서 설명한 내용은 Armv8 아키텍처 관점에서 다음과 같이 바꿔서 설명할 수 있습니다.

 서브루틴을 호출하면 프로세스의 스택 공간에 레지스터를 푸시한다.
 'BL [주소]' 명령어를 실행해 서브루틴으로 분기하면 Arm 코어는 링크 레지스터인 X30에 복귀할 주소를 업데이트한다.
 서브루틴을 호출할 때 전달되는 인자는 X0 ~ X7 레지스터에 저장된다.
 함수의 리턴값은 X0 레지스터에 저장된다.

위 내용을 보면 알 수 있듯이 Armv7 아키텍처에서 다룬 AAPCS의 주요 개념은 Armv8 아키텍처에 거의 그대로 적용됩니다. 서브루틴을 호출할 때 사용되는 레지스터와 어셈블리 명령어만 다릅니다. 

이번 포스트에서는 Armv8 아키텍처에서 정의된 레지스터 목록 중에서 AAPCS와 관련된 레지스터를 소개합니다. Armv7 아키텍처에서 소개한 AAPCS와 유사한 개념이 많으니 차이점 위주로 설명하겠습니다.

[정보] AAPCS64란?
이번 장에서 소개하는 Armv8 아키텍처의 AAPCS는 64비트를 기준으로 설명하는데, 이를 AAPCS64로 표기합니다.

 

<강의 영상>

 

+ Recent posts