이번 장에서 서브 루틴을 호출하면 다음과 같은 동작을 수행한다고 배웠습니다.
* R0~R3 레지스터에 함수의 인자를 저장
* 서브 루틴은 push와 pop 명령어를 사용해 링크 레지스터를 백업
* 서브 루틴에서 반환하는 값을 R0 레지스터에 저장
이번 장에서 소개된 add_func() 함수를 호출하는 과정에서 실행되는 어셈블리 명령어는 요약하면 다음과 같습니다.
01 10498: e51b100c ldr r1, [fp, #-12]
02 1049c: e51b0008 ldr r0, [fp, #-8]
03 104a0: ebffffe3 bl 10434 <add_func>
...
04 00010434 <add_func>:
05 10434: e92d4800 push {fp, lr}
06 10438: e28db004 add fp, sp, #4
07 1043c: e24dd010 sub sp, sp, #16
...
08 1046c: e1a00003 mov r0, r3
09 10470: e24bd004 sub sp, fp, #4
10 10474: e8bd8800 pop {fp, pc}
01~10번째 줄까지, 10개 정도의 어셈블리 명령어가 실행됩니다.
그런데 다음과 같은 상황에서 함수 호출 시 실행되는 어셈블리 명령어는 오버헤드가 될 수 있습니다.
* 함수가 실행하는 코드는 1~2줄 밖에 안되는 간단한 코드
* 매우 자주 호출되는 함수
이 경우 inline 키워드로 함수를 선언하면, 컴파일러는 함수의 코드를 함수를 호출한 부분에 복사합니다. 결국 함수 호출 시 실행되는 명령어를 줄일 수 있습니다.
AAPCS는 최적화 이외에도 실전 소프트웨어 개발에 활용될 수 있는 내용이 많습니다. 이는 Armv7와 Armv8 아키텍처에 공통으로 적용될 수 있는 내용이라, 8장에서 소개합니다.
Written by <디버깅을 통해 배우는 리눅스 커널의 구조와 원리> 저자

최근 덧글