본문 바로가기

Background

x12-x17 (caller-saved) register

x12에서 x17 레지스터는 RISC-V 아키텍처에서 추가 함수 인자를 전달하고 연산에 사용되는 범용 레지스터입니다. 이 레지스터들은 각각 **a2**부터 **a7**이라는 이름으로 불리며, 함수 호출 시 세 번째부터 여덟 번째 인자까지 전달하는 용도로 사용됩니다. 또한, 함수 내에서 연산을 수행하거나 임시 데이터를 저장하는 데도 사용될 수 있습니다.

x12 (a2) ~ x17 (a7) 레지스터의 주요 역할과 사용 이유

  1. 추가 함수 인자 전달:
    • a2 (x12)에서 a7 (x17)까지의 레지스터는 함수 호출 시 세 번째부터 여덟 번째 인자를 전달하는 데 사용됩니다. RISC-V 아키텍처는 함수 호출 시 최대 8개의 인자를 레지스터로 전달할 수 있도록 설계되어 있어, 메모리 접근 없이 빠르게 인자를 전달할 수 있습니다.
    • 만약 함수가 8개 이상의 인자를 필요로 하는 경우, 나머지 인자는 스택을 통해 전달됩니다. 이 방식은 흔히 사용하는 인자를 모두 레지스터에 담아 함수 호출의 속도를 최적화하기 위함입니다.
  2. 범용 임시 레지스터:
    • a2 ~ a7 레지스터는 함수 내에서 연산을 수행하거나 중간 값을 저장하는 데도 사용할 수 있습니다. 이들은 caller-saved 레지스터로, 함수가 호출될 때 호출하는 측(caller)이 값을 관리하므로, 호출된 함수(callee)는 자유롭게 이들 레지스터를 사용할 수 있습니다.
    • 예를 들어, 함수 내에서 복잡한 계산을 수행할 때 중간 결과를 저장하거나, 다른 레지스터들 간의 값을 교환할 때 유용하게 사용됩니다.
  3. 함수 반환 값의 확장:
    • 함수가 여러 개의 반환 값을 제공하는 경우, a2 ~ a7 레지스터도 반환 값을 저장하는 용도로 사용될 수 있습니다. 기본적으로 a0과 a1 레지스터를 사용하지만, 두 개 이상의 반환 값을 반환해야 하는 경우 추가 레지스터들을 활용할 수 있습니다.
    • 예를 들어, 구조체나 복합 데이터 타입을 반환할 때, 여러 레지스터를 동시에 사용하여 빠르게 데이터를 반환할 수 있습니다.

x12 - x17 사용 예시

다음은 x12 (a2)부터 x17 (a7) 레지스터가 함수 인자 전달과 임시 저장소로 사용되는 예시입니다:

  • 함수 호출 시 인자 전달
# a0 (x10)에 첫 번째 인자 전달
# a1 (x11)에 두 번째 인자 전달
# a2 (x12)에 세 번째 인자 전달
# a3 (x13)에 네 번째 인자 전달
addi x10, x0, 5      # 첫 번째 인자를 5로 설정
addi x11, x0, 10     # 두 번째 인자를 10으로 설정
addi x12, x0, 15     # 세 번째 인자를 15로 설정
addi x13, x0, 20     # 네 번째 인자를 20으로 설정
jal ra, my_function  # my_function 호출

이 예시에서는 a0부터 a3까지 각각 5, 10, 15, 20의 값을 설정한 후 my_function을 호출합니다. my_function 내에서는 이 인자들에 접근하여 작업을 수행할 수 있습니다.

  • 함수 내부에서 임시 값 저장
my_function:
    add a4, a0, a1   # a4에 a0 + a1의 결과 저장
    mul a5, a2, a3   # a5에 a2 * a3의 결과 저장
    sub a6, a5, a4   # a6에 a5 - a4의 결과 저장
    ret              # 함수 종료

이 예시에서 my_function 함수는 a0에서 a3까지의 값을 이용하여 연산을 수행하고, 그 중간 결과를 a4 (x14), a5 (x15), a6 (x16)에 저장합니다. 이처럼 a2 ~ a7 레지스터는 임시 저장소로 유용하게 활용될 수 있습니다.

caller-saved 레지스터 관리

  • a2 (x12) ~ a7 (x17)은 caller-saved 레지스터입니다. 이는 함수가 호출될 때, 호출하는 측이 이 레지스터들의 값을 저장하고, 호출된 함수가 종료된 후에 복원해야 함을 의미합니다.
  • 함수가 호출될 때 중요한 값이 이 레지스터들에 저장되어 있다면, 함수 호출 전에 해당 값을 스택에 저장하고, 함수가 종료된 후에 다시 스택에서 복원해야 합니다. 이는 다른 함수가 호출되더라도 기존 데이터가 손실되지 않도록 보장합니다.

레지스터 기반 인자 전달의 장점

  • RISC-V 아키텍처에서 a2 ~ a7을 사용하는 방식은 레지스터 기반 인자 전달의 장점을 극대화합니다. 일반적으로, 메모리 접근은 레지스터 접근보다 훨씬 느리기 때문에, 인자들을 레지스터로 전달하면 함수 호출의 속도를 크게 향상시킬 수 있습니다.
  • 특히, 많은 인자들이 필요한 함수에서도 대부분의 인자를 레지스터로 전달할 수 있어 함수 호출 오버헤드를 줄이고, 함수가 더 빠르게 실행될 수 있도록 설계되었습니다.

x12-x17의 설계 철학

x12에서 x17까지의 레지스터는 RISC-V의 효율적이고 단순한 설계 철학을 반영합니다. 이 레지스터들은 주로 함수 호출에서 인자를 전달하는 데 사용되지만, 함수 내부에서 임시 데이터를 저장하는 용도로도 활용될 수 있어, 프로그램 작성 시 매우 유연하게 사용할 수 있습니다. caller-saved 특성 덕분에, 이들 레지스터는 함수 호출 간의 데이터 일관성을 유지하면서도 빠르고 효율적인 연산을 가능하게 합니다.

결론

x12 (a2)부터 x17 (a7) 레지스터는 RISC-V 아키텍처에서 함수 인자 전달임시 데이터 저장의 중요한 역할을 합니다. 이 레지스터들은 최대 8개의 인자를 빠르게 전달할 수 있는 레지스터 기반 함수 호출 구조를 지원하며, 함수 내부에서 임시 값을 효율적으로 관리할 수 있게 합니다. 이러한 설계는 RISC-V의 간결하고 효율적인 함수 호출 및 연산 구조를 구현하는 데 필수적인 요소입니다.

'Background' 카테고리의 다른 글

x28~x31(Temporaries) register  (0) 2024.10.20
x18-x27 (callee-saved) register  (0) 2024.10.20
x10-x11 (caller-saved) register  (0) 2024.10.20
x9(callee-saved s1) register  (0) 2024.10.20
x8(saved s0/frame pointer) register  (0) 2024.10.20