7. 분기 명령어#

이들은 보통 레이블로 지정된 대상 위치로 실행이 점프하게 합니다(label() 어셈블러 지시문 참조). 조건부 분기와 it 및 ite 명령어는 애플리케이션 프로그램 상태 레지스터(APSR)의 N(음수), Z(영), C(자리올림), V(오버플로) 플래그를 테스트하여 분기를 실행할지 여부를 결정합니다.

노출된 대부분의 어셈블러 명령어(이동 연산 포함)는 플래그를 설정하지만, 값을 테스트할 수 있도록 명시적인 비교 명령어가 있습니다.

조건 플래그의 의미에 대한 추가 세부 정보는 comparison instructions 절에 제공됩니다.

7.1. 문서 표기 규칙#

표기: Rm은 ARM 레지스터 R0-R15를 나타냅니다. LABEL은 label() 어셈블러 지시문으로 정의된 레이블을 나타냅니다. <condition>은 다음 조건 지정자 중 하나를 나타냅니다:

  • eq 같음(결과가 0이었음)

  • ne 같지 않음

  • cs 자리올림 설정됨

  • cc 자리올림 해제됨

  • mi 마이너스(음수)

  • pl 플러스(양수)

  • vs 오버플로 설정됨

  • vc 오버플로 해제됨

  • hi > (부호 없는 비교)

  • ls <= (부호 없는 비교)

  • ge >= (부호 있는 비교)

  • lt < (부호 있는 비교)

  • gt > (부호 있는 비교)

  • le <= (부호 있는 비교)

7.2. 레이블로 분기#

  • b(LABEL) 무조건 분기

  • beq(LABEL) 같으면 분기

  • bne(LABEL) 같지 않으면 분기

  • bge(LABEL) 크거나 같으면 분기

  • bgt(LABEL) 크면 분기

  • blt(LABEL) 작으면 분기(<) (부호 있음)

  • ble(LABEL) 작거나 같으면 분기(<=) (부호 있음)

  • bcs(LABEL) 자리올림 플래그가 설정되어 있으면 분기

  • bcc(LABEL) 자리올림 플래그가 해제되어 있으면 분기

  • bmi(LABEL) 음수이면 분기

  • bpl(LABEL) 양수이면 분기

  • bvs(LABEL) 오버플로 플래그가 설정되어 있으면 분기

  • bvc(LABEL) 오버플로 플래그가 해제되어 있으면 분기

  • bhi(LABEL) 더 크면 분기(부호 없음)

  • bls(LABEL) 더 작거나 같으면 분기(부호 없음)

7.3. 긴 분기#

위에 나열된 분기 명령어가 생성하는 코드는 분기 대상을 지정하는 데 고정된 비트 폭을 사용하며, 이는 PC 상대적입니다. 따라서 분기 명령어가 그 대상에서 멀리 떨어진 긴 프로그램에서는 어셈블러가 “branch not in range” 오류를 생성합니다. 이는 다음과 같은 “wide” 변형으로 극복할 수 있습니다

  • beq_w(LABEL) 같으면 긴 분기

와이드 분기는 명령어를 인코딩하는 데 4바이트를 사용합니다(표준 분기 명령어의 2바이트와 비교하여).

7.4. 서브루틴(함수)#

서브루틴에 진입할 때 프로세서는 반환 주소를 레지스터 r14에 저장하며, 이는 링크 레지스터(lr)로도 알려져 있습니다. 서브루틴 호출 다음 명령으로의 반환은 링크 레지스터로부터 프로그램 카운터(r15 또는 pc)를 갱신하여 수행됩니다. 이 과정은 다음 명령어들로 처리됩니다.

  • bl(LABEL)

반환 주소를 링크 레지스터(r14)에 저장하면서 LABEL 다음 명령으로 실행을 이전합니다.

  • bx(Rm) Rm으로 지정된 주소로 분기.

일반적으로 bx(lr)는 서브루틴에서 반환하는 데 사용됩니다. 중첩된 서브루틴의 경우 내부 서브루틴 호출을 수행하기 전에 외부 스코프의 링크 레지스터를 (보통 스택에) 저장해야 합니다.