간접 분기

간접 분기(, 간접 브랜치, 간접 점프, 레지스터-간접 점프)는 다음 인스트럭션의 메모리 주소를 런타임에 매개 변수로 받아들이는 프로그램 제어 명령어 중 하나이다. 간접 분기의 다음 인스트럭션 주소는 레지스터나 메모리에 의해 간접적으로 지정되는데, 가령 간접 분기의 매개 변수로 어떤 메모리 주소가 주어졌다면, 다음 인스트럭션의 주소는 이 메모리 주소가 아닌 "이 메모리 주소에 저장된 메모리 주소"가 된다. 간접 분기의 다음 인스트럭션 주소는 이 인스트럭션이 실행되기 전까지는 알 수 없다.

간접 분기는 조건 분기문(예: if 문)이나 다중 분기문(예: switch 문)을 구현하는데 유용한데, 가령 다음 실행할 코드가 변수의 값에 의해 결정된다면, 분기 테이블에서 이 값으로 다음 인스트럭션의 주소를 찾아낸 다음 간접 분기를 통해 점프할 수 있다. 경우의 수가 제한적인 경우에는 변수 값에 따라 다음 인스트럭션 주소를 레지스터에 직접 입력시킨 후에 간접 분기로 하여금 제어 흐름을 점프하도록 할 수도 있다.

비슷한 방식으로, 서브루틴 호출 역시 메모리에 저장된 서브루틴 주소를 통해 간접적으로 이루어질 수 있다. 일반적으로 함수 포인터가 이러한 간접적인 서브루틴 호출을 이용해 구현된다.

간접 분기는 예측적 실행과 결합되어 스펙터 공격을 가능하게 한다. 이에 대한 방어책으로 GCC 8.1 버전부터 간접 분기와 관련된 코드 생성 시에 스펙터 공격에 대한 방어 메커니즘을 수동으로 지정해줄 수 있는 옵션들이 추가될 예정이다. (-mindirect-branch=, -mfunction-return=, -mindirect-branch-register=).

어셈블러 구문 예시 
{|
| MSP430:  ||br r15
|-
| SPARC:  ||jmpl %o7
|-
| MIPS:   ||jr $ra
|-
| x86 (AT&T Syntax):     ||
|-
| x86 (Intel Syntax):     ||
|-
| ARM:    ||
|-
| 아이테니엄 (x86 계열):   ||br.ret.sptk.few rp
|-
| 6502:   ||jmp ($0DEA)
|-
| 65C816: ||jsr ($0DEA,X)
|-
| 6809: ||jmp [$0DEA], jmp B,X, jmp [B,X]
|-
| 6800: ||jmp 0,X
|-
| Z80: ||jp (hl)
|-
| 인텔 8080: ||pchl
|-
| IBM 시스템 z: ||bcr cond,r1
|}

참조 

 분기 테이블
 간접 스레딩

참고 문헌 

기계어
제어 흐름