Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

8179
1390
307630


[Arm프로세서] AAPCS: Armv7: 브랜치 명령어(bl) Armv7: 함수 호출 규약

C 프로그래밍으로 함수를 호출하는 구문을 어셈블리 코드로 확인하면 'bl [심벌 주소]'와 같은 명령어가 보입니다. 이번 절에서는 bl 명령어의 정의를 소개하고, 예제 코드를 분석하면서 bl 명령어의 사용법을 살펴보겠습니다.

bl 명령어란

이번에도 Arm 스팩 문서에서 bl 명령어를 설명하는 부분을 소개합니다.

5.4 Branches

Calls to subroutines, where it is necessary for the return address to be stored in the link register, use the BL instruction.
(출처: DEN0013D_cortex_a_series_PG.pdf)

위 내용은 "BL 명령어를 사용하면 서브 루틴을 호출하는데, 서브 루틴을 호출한 다음에 복귀할 주소가 LR(R14) 레지스터에 저장된다"라고 요약할 수 있습니다.

이어서 명령어의 표기법을 보겠습니다.

BL label

표기법의 왼쪽에 label이 있는데 이는 분기할 주소를 의미합니다. 'BL label' 는 지정된 주소로 분기하는 동작을 수행합니다.

예제 코드 분석으로 bl 명령어의 사용법 알아보기

이번에는 다음과 같은 간단한 예제 코드를 보면서 BL 명령어의 용법을 알아 봅시다.

01 0x1047c      <main>:
02                             ....
03 0x104a0                 bl 104c4 <add_func>
04 0x104a4                 str     r0, [fp, #-16]
...
05 0x104c4 <add_func>:
06 0x104c8                 add r0, r1, r2 
07 0x104cc                 BL lr 

먼저 3번째 줄을 보겠습니다.

03 0x104a0                 bl 104c4 <add_func>

'bl 104c4' 명령어는 104c4 주소로 분기하는 동작을 수행하는데, 104c4는 add_func() 함수의 시작 주소입니다. 이를 쉽게 설명하면 add_func() 함수가 호출되는 동작이라고 볼 수 있습니다.

여기서 기억할 점은 3번째 줄을 실행하면 복귀할 주소가 LR(R14) 레지스터에 업데이트된다는 사실입니다. 예제 코드 기준으로는 03번째 줄 다음에 있는 04번째 줄의 주소인 0x104a4가 LR 레지스터에 저장됩니다.

정리하면 'bl 104c4' 명령어가 실행되면 동시에 다음과 같은 동작을 수행합니다.

   * add_func() 함수의 시작 주소인 0x104c4 주소로 분기
   * LR 레지스터는 서브 루틴 호출 후 복귀할 주소인 0x104a4로 업데이트됨

[정보]
이 밖에도 Arm 아키텍처에서는 다음과 같은 브랜치 명령어를 지원합니다.

B label

그런데 B 명령어를 실행하면 label로 지정된 주소로 분기하는데, label 주소에 해당되는 서브 루틴으로 분기한 다음에 복귀할 LR 레지스터가 업데이트되지 않습니다. 따라서 B 명령어를 사용해 특정 주소나 심벌을 브랜치하는 동작을 직접 어셈블리 명령어를 입력해 구현할 경우에는 복귀할 주소를 지정해 줘야 합니다.


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

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

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




덧글

댓글 입력 영역