이번 장에서는 Arm 프로세서에서 함수를 호출하거나, 인자를 전달하고 리턴되는 Register 들의 역할을 살펴보고
프로시저가 무엇인지 알아보자.
1. Procedure Call
- 형식 : BL <Label>
- 리턴 주소는 lr 레지스터에 저장된다. (리턴 주소란? 해당 명령어를 마치고 다음으로 갈 주소)
- "Label"로 jump 하는 의미를 갖는다.
예시
838c의 <sum> 명령어가 실행될 때, 리턴 주소는 8390이며, lr에 들어가게 된다.
이후 <sum> 프로시저가 끝나면 8390 줄이 실행되게 된다.
2. Procedure Return
프로시저 콜이 있다면, 당연히 리턴도 있어야 할 것이다.
여기서는 자연스러운 리턴 대신 직접 할 수 있는 방법을 설명한다.
1) bx 명령어
bx lr은 레지스터 lr에 담긴 주소 (가리키는 주소)로 Jump 한다는 의미를 가지고 있다.
2) stack 사용
1) 과 같은 방식을 사용하면, 중간에 lr 레지스터에 들어있는 값이 바뀌었을 때 꽤나 골치 아픈 상황이 생긴다.
lr이 있는 이유는 있던 곳으로 되돌아가기 위함인데, 되돌아갈 곳이 바뀌면 꿈에서 깨어나지 못할 수 있기 때문이다.
따라서 다음과 같이 stack을 사용하는 편이 좋다.
위 방식은 여러 개의 원소를 stack에 push, pop하는 STM(stack multiple) 방식이다.
특징은 넣은 순서대로 pop할 때 대입된다는 것인데, 위 코드대로라면, pc에 lr이 대입된다.
pc는 현재 프로그램의 위치이므로 lr이 대입되면 왔던 그대로 빠져나올 수 있다.
Stack-Based 언어의 특징
- 여러 번 불려도 유지가 되어야 한다. (재귀에서 빠져나올 수 있어야 한다.)
- 인자, 로컬 변수, 리턴 주소를 저장할 공간이 필요하다.
- 왔던 그대로 나올 수 있어야 한다.
뭐 계속 반복되는 이야기다.
Stack Frame
스택 프레임은 스택 내부 구조를 가리킨다.
내용
- 지역 변수들
- 리턴 정보 (주소, 리턴 값)
- 임시 공간
작업
- 프로시저에 들어갈 때 "set-up" code를 할당한다.
- 프로시저 리턴 시 "Finish" code 를 재할당한다.
3. ARM Procedure Call Standard
ARM 프로시저 콜의 기본적인 규칙이다. 매우 중요하고 꼭 알아야 한다.
- 리턴 주소는 lr(r14) 레지스터에 저장한다.
- 만약 다른 프로시저를 부를 시, 현재 lr은 반드시 스택에 보관해둬야 한다.
- r0 ~ r3 레지스터는 첫 4개의 인자로 들어갈 수 있다.
- 리턴 값은 r0 레지스터에 저장된다.
- r0 ~ r3 은 scratch register (값이 바뀔 수도 있어 not recover 하다.)
'System Programming(ARM)' 카테고리의 다른 글
4. Advanced ARM Instructions (0) | 2020.12.15 |
---|---|
5. 작성한 C 코드를 어셈블러로 변환하기 (arm) (0) | 2020.12.15 |
7. Linking (2) | 2020.12.15 |
11. System-Level I/O (0) | 2020.12.15 |
8. Two-pass Assembler (0) | 2020.12.06 |