반도체 소프트웨어

요약 10. AAPCS ARMv7 본문

CPU Architecture/ARM Architecture

요약 10. AAPCS ARMv7

반도체 소프트웨어 엔지니어 2024. 1. 3. 16:48
  1. AAPCS(ARM Architecture Procedure Call Standard): 함수 호출을 위한 세부 규칙
    1. calling convention, 함수호출규약 이라고도 부름
    2. CPU관점에서 함수는 서브루틴(독립적으로 실행되는 소프트웨어 모음)
    3. 함수 호출 동작은 cpu 아키텍처 도움 받아야 가능(c언어에서 지원하는 기능 X)
    4. AAPCS 내용
      1. 함수 호출시 레지스터를 어떻게 사용하는지
      2. 함수 반환시 return 구문을 통해 값을 어떻게 반환하는지
      3. 함수 호출시 스택을 어떻게 사용하는지
  2. AAPCS를 잘알아야하는 이유
    1. 실전 프로젝트에서 디버깅을 잘하기위한 기반 지식
      1. 모든 코드는 프로세스 스택 공간에서 실행
      2. 지역변수는스택공간에 저장
    2. 프로그램 근본 동작 원리 파악:  CPU동작하는 방식을 이해하기 위한 초석
    3. AAPCS 염두에 둔 코드 작성
      1. 배열 선언은 프로세스 스택사용하므로 최소 크기로 선언
      2. 함수 호출 깊이 고려
      3. 함수에 전달되는 인자 개수 최소화
  3. 스택 자료 구조
    1. TOP(stack pointer)은 가장 최근에 삽입된 데이터 위치를 나타냄
      1. 스택 공간: 연속적인 메모리 공간으로서 지역 변수를 저장하거나 서브루틴에 전달되는 추가 인자를 저장하는데 쓰인다
      2. 커널에서 프로세스 스택

        1. 일정한 크기 메모리를 잘라서 프로세스에게 스택을 할당
        2. ARMv7 0x2000 / ARMv8 0x4000 스택 공간 할당
        3. 높은주소 -> 낮은주소 방향으로 함수 호출
        4. 스택은 정적메모리이며 할당되면 변경불가능
        5. 부트로더는 좀 더 적은 스택 사용
      3. 스택프레임과 스택포인터

        1. 스택 프레임: 함수 호출 시 생성되는 메모리 공간으로, 함수의 실행에 필요한 로컬 변수, 매개변수, 복귀 주소 등을 저장하는 데 사용
        2. 프레임 포인터: 스택 프레임 내에서 현재 함수의 시작 지점을 가리키는 포인터이며, 프레임 포인터는 보통 스택 프레임의 맨 아래에 위치하고 로컬 변수 및 매개변수의 오프셋을 계산하는 데 사용
        3. 다른 함수가 다른 함수의 스택프레임에 접근할 수 없다.
  4. ARM 아키텍처별 AAPCS 관련 레지스터
  5. AAPCS ARMv7
    1. 함수 호출 규약은 CPU 아키텍처마다 다름 ex) RISC-V, x86 등
    2. 결론적으로는 c언어가 있다고 함수호출이 처리되는 것이 아니라 AAPCS가 구현되어있어야 가능한 것
    3. 관련 레지스터
      1. R13: OS의 스택 포인터로 사용
        1. 모든 모드에 뱅크드된 레지스터
        2. R13이 업데이트되면 뱅크드 레지스터도 같이 업데이트됨
        3. 서브루틴을 호출한 이전 함수를 찾거나 등 프로세스 실행 흐름을 저장하기 위해서
        4. 즉 뱅크드함으로써 스택 공간 등에 백업할 필요가 없음
      2. R14: BL로 서브루틴(함수, 레이블) 주소 분기 후에 복귀할 주소 저장 레지스터
    4. 명령어: BL, PUSH, POP

      1. PUSH
        1. 프로세스 스택의 연속적인 공간에 지정한 여러 레지스터 값을 푸시
        2. SP 레지스터 업데이트하면서 지정된 레지스터를 푸시 ex) PUSH {R3, R4, R5, R14}
        3. 가장 첫 SP 값은 부트코드에서 초기화됨
        4. 아마 스택메모리오버플로우를 방지하기 위해서 push할 레지스터 전체 크기만큼 우선 sp를 감소시킨 뒤에 그 위치부터 반대로 데이터를 저장하네(스택메모리벗어나나 확인하고 데이터를 실제적으로 저장하는 것)
      2. Pop
        1. 프로세스 스택에 있는 데이터를 지정된 레지스터로 빼냄
        2. pop {R4, R5, R6, FP, PC}
        3. pop대신에 ldm 명령어를 쓰기도하네 (함수 복귀시에는 PC레지스터에 이전 LR값 저장)
      3. BL

        1. BL 명령어를 실행하면 서브루틴을 호출하며, 복귀할 주소가 R14에 저장된다
        2. PC = <label>
  6. AAPCS 최적화 코드
    1. 함수 인자 개수는 4개 이하로 제한: 인자 개수가 많아지면 레지스터에 저장안하고 스택에 저장하고 관련 어셈블리어 명령어 개수도 증가하므로 줄이는게좋음
    2. 함수 반환형은 워드 단위로 지정: 워드(32bit) 단위가 넘어가면 반환 데이터 저장을 위해 레지스터 여러개를 사용하므로 그만큼 어셈블리명령어가 추가적으로 필요하다
    3. 매우 자주 호출되는 비교적 짧은 함수는 inline 키워드로 선언
      1. 함수호출하면 기본적으로 사용되는 어셈블리어 명령어가 있음
      2. 자주호출되면 계속 중복 사용되는 현상 발생
      3. Inline 명령어를 통해 함수호출을 아예 코드로 치환해서 컴파일하면 효율적이다

 

출처: 인프런, "시스템 소프트웨어 개발을 위한 Arm 아키텍처의 구조와 원리", https://inf.run/FiFG

'CPU Architecture > ARM Architecture' 카테고리의 다른 글

요약 11. AAPCS ARMv8  (0) 2024.01.04
요약 9. GIC - 인터럽트 컨트롤러  (0) 2024.01.02
요약 8. ARMv8 익셉션  (0) 2023.12.31
요약 7. ARMv7 익셉션  (0) 2023.12.31
요약 6. ARMv8 익셉션 레벨  (0) 2023.12.31