Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

8179
1390
307630


[Arm프로세서] AAPCS: Armv8: 브랜치와 복귀 명령어 - RET Armv7: 함수 호출 규약

마지막으로 AAPCS와 연관된 명령어로 RET 에 대해 알아봅시다. 다음은 Arm 스팩 문서에서 명시된 RET 명령어에 대한 내용입니다.

C6.2.219 RET

Return from subroutine branches unconditionally to an address in a register, with a hint that this is a subroutine return.
[출처: DDI0487Fc_armv8_arm.pdf]

Armv8 아키텍처에서 꼭 알아둬야 할 명령어가 RET입니다. RET는 Return from subroutine의 약자인데, 서브 루틴을 호출한 후 복귀할 주소가 담긴 X30 레지스터의 값을 PC로 로딩하는 역할을 수행합니다.

여기서 X30 레지스터의 값을 PC에 로딩하는 동작은 구체적으로 어떻게 해석할 수 있을까요?

   "바로 서브 루틴으로 복귀하는 동작을 의미합니다."

서브 루틴을 호출할 때 bl '주소'와 같은 포멧의 명령어를 실행하는데, 이 때 Arm 코어는 복귀할 주소는 X30 레지스터에 업데이트합니다. 그런데 RET 명령어를 수행하면 X30 레지스터의 값을 PC에 로딩해 복귀할 주소로 분기하게 됩니다. 

Armv7 아키텍처는 pop 명령어에서 pc를 지정해 프로세스의 스택 공간에 저장된 링크 레지스터(R14)의 값을 PC에 직접 로딩합니다. 대신 Armv8 아키텍처는 RET 명령어를 실행해야만 X30 레지스터의 값을 PC에 넣어줍니다.

이번에는 간단한 예제 코드를 보면서 RET 명령어의 동작을 알아봅시다.

01 <__fork>:
02 9f4a8:   a9bc7bfd    stp x29, x30, [sp, #-0x40]!
03 132405    9f4ac:   52800000    mov w0, #0x0                     
...
04 9f5f8:   a8c47bfd    ldp x29, x30, [sp], #0x40
05 9f5fc:   d65f03c0    ret

먼저 복습하는 차원으로 02번째와 04번째 줄을 분석하겠습니다.

02번째 줄은 0x40바이트만큼 스택 공간을 확보하면서 x29와 x30 레지스터의 값을 스택에 푸시하는 동작입니다. stp 명령어를 분석할 때는 가장 오른쪽에 '!'가 있는 지 주의하면서 볼 필요가 있습니다.

04번째 줄은 스택에 저장된 데이터를 x29, x30 레지스터에 다시 로딩하면서 스택의 주소를 0x40만큼 업데이트하는 동작입니다. 여기서 x30 레지스터는 복귀할 주소가 저정돼 있습니다.

이제 05번째 줄을 분석할 차례입니다. 05번째 줄을 실행하면 X30 레지스터의 값을 PC에 넣어주게 되고, 복귀할 주소로 분기하게 됩니다.

이번 절에서는 AAPCS와 관련된 어셈블리 명령어를 소개했습니다.

다음 절에서는 AAPCS와 연관된 레지스터를 소개하고 이번 절에 소개한 어셈블리 명령어가 실행되면 관련 레지스터가 어떻게 바뀌는지 살펴보겠습니다.

Written by <디버깅을 통해 배우는 리눅스 커널의 구조와 원리> 저자




덧글

댓글 입력 영역