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

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

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

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

어셈블러 구문 예시 편집

MSP430:   br r15
SPARC:   jmpl %o7
MIPS:    jr $ra
x86 (AT&T Syntax):      jmp *%eax
x86 (Intel Syntax):      jmp eax
ARM:     mov pc, r2
아이테니엄 (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[2]

참조 편집

참고 문헌 편집

  1. Larabel, Michael (2018년 1월 14일). “Spectre Mitigation Added To GCC 8, Seeking Backport To GCC 7”. 2018년 1월 20일에 원본 문서에서 보존된 문서. 2018년 1월 19일에 확인함. 
  2. “z/Architecture - Principles of Operation” 4판. IBM. May 2004 [1990]. SA22-7832-03. 2016년 3월 4일에 원본 문서에서 보존된 문서. 2018년 5월 26일에 확인함.