반도체 소프트웨어

요약 11. AAPCS ARMv8 본문

CPU Architecture/ARM Architecture

요약 11. AAPCS ARMv8

반도체 소프트웨어 엔지니어 2024. 1. 4. 14:50
  1. 개요
    • 함수 호출은 ARM 코어 도움을 받아야 가능
    • BL 이후 복귀할 주소를 하드웨어적으로 x30(LR)에 업데이트
    • RET 명령어 실행하면 x30 값이 PC로 업데이트
  2. 스택 오버플로우, 스택 CORRUPTION이 발생하면 디버깅시에 스택 콜 스택 조차 제대로 확인하지 못할 수 있다
  3. AAPCS 관련 레지스터

    • sp 스택포인터
      • 사용중인 프로세스의 스택 위치 저장
      • 익셉션 레벨별로 sp 레지스터 존재
    • X30: 링크 레지스터
    • x0-x7: 함수 전달 인자
    • X0: 함수반환
  4. 스택 푸시 명령어
    • STP(store pair of registers): 베이스 레지스터(피연산자)가 가리키는 값을 기준으로 지정된 레지스터를 주소에 저장
    • 두 개 레지스터를 주소에 저장하는 기본적인 기능 수행 -> 베이스 레지스터가 sp이면 스택에 푸시하는 동작 실행
    • 주로 함수 심볼 가장 앞 부분에 사용해서 LR을 스택에 저장해놓는 작업 등을 진행
    • 사용 예제
      • stp x29, x30, [sp, #-0x20]! -> 스택에 레지스터값을 푸시하면서 sp레지스터를 업데이트
      • stp x28, x27, [sp, #0x10] -> 스택에 레지스터 값만 푸시(sp레지스터 업데이트 X), (느낌표에 따라 명령어 동작이 다름)
  5. 스택 팝 명령어
    • LDP(Load pair of registers): 베이스 레지스터가 가리키는 주소에 저장된 데이터를 지정된 레지스터에 로딩함
    • 베이스 레지스터가 SP이면 팝 동작과 동일
    • 함수가 실행을 마무리하는 루틴에 사용됨
    • 사용 예제
      • LDP x28, x27, [sp, #0x10]
        1. 스택의 데이터를 지정된 레지스터에 업데이트
        2. sp +  #<imm>
        3. sp + #<imm>주소 + 0x8
        4. 위 두 주소에 저장된 값을 레지스터에 저장
      • LDP x29, x30, [sp] #0x20
        1. 스택의 데이터를 지정된 레지스터에 업데이트한 뒤에 #imm 만큼 sp업데이트
        2. Sp
        3. sp주소 + 0x8
        4. 위 두 주소에 저장된 값을 레지스터에 저장
        5. sp += #0x20 로 SP 업데이트
  6. 분기 명령어
    • BLR: 레지스터에 있는 주소값으로 분기하는 명령어 Ex) BLR x2
    • 함수 포인터 호출시에 주로 사용
    • 함수호출, 프로시저콜이 어느 과정에서든 정상적으로 동작하기 위해서는 ARM 아키텍처의 하드웨어적인 도움이 필요하다
  7. 복귀 명령어
    • RET
    • X30 레지스터 값을 PC에 로딩
    • v7과 달리 v8에서 PC 레지스터는 직접적으로 수정하지 못하고 RET명령어 사용해서 간접적으로 수정 가능
    • 함수호출시에 복귀할주소를 X30에 저장도 하고 스택에 푸시도함 ex) stp x29, x30,[sp, #-0x10]! (함수 중복 호출시에는 X30저장한 것만으로는 부족하니깐)
  8. AAPCS를 사용한 소프트웨어 최적화
    • 함수 인자 개수는 8개 이하로 제한: 9번째 인자부터는 스택 공간에 저장하므로 어셈블리 명령어가 늘어남
    • 매우 자주 호출되는 함수는 inline 키워드로 선언
      • 함수 심벌을 생성하지 않고 함수 코드를 복사해서 사용
      • ldp, stp, ret 같은 명령어가 실행되지 않음
  9. stack corruption

    • 원인
      • 메모리 오염으로 인해 잘못된 데이터가 저장되어있는것
      • 배열 memcpy 잘못사용하면 발생
      • 스택을 벗어난 메모리 공간에 스택 푸시
    • 해결책: 컴파일러 기능 사용하면 미리 원인 파악 혹은 제거할 수 있음
  10. stack overflow

    • 원인
      • 스택 메모리는 정적 공간이기에 처음에 할당된 영역을 넘어가면 스택 오버플로우 발생
      • 이전 스택포인터값을 프레임 포인터
    • 해결책
      • IRQ STACK 사용하면 인터럽트 처리시에 프로세스스택이 아닌 IRQ스택 사용하므로 방지 가능
      • 컴파일러 기능 최대한 사용(stack canary)
      • 배열 크기 최적화 등

 

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

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

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