跳转到内容

間接分支

维基百科,自由的百科全书


間接分支(indirect branch)也稱為間接跳躍(indirect jump)或暫存器間接跳躍(register-indirect jump),是机器语言指令集架構控制流程的一種方法。在機器語言裡,一般的控制流程會直接標示接下來要執行程式的位址(直接分支),而間接分支是在參數中標示要執行的記憶體位址。像「分支到r1寄存器所記錄的位置」即為一例,此例中,接下來要執行程式的位置在r1寄存器裡,要執行完這個指令才知道接下來要執行的程式。間接分支也可以依記憶體中的值為準。

在程式裡,間接分支可以用在像多路分支英语multiway branch的應用上(類似高階語言的switch指令)。例如程式可以可以根據輸入值,到分支表中查看對應輸入指令的位置,放在暫存器中,再進行間接分支。因此間接分支可以有效的處理程式的流程控制。

子程序的呼叫也可以用類似的方式間接呼叫,呼叫程式的位置是由記憶體中的值決定。高階語言的函数指针就會用此方式實現。

間接分支和間接呼叫的目標是計算出來的,若程式有錯誤,有可能會分支或呼叫到不正確的位置(例如沒有程式碼的位置,或是未預期程式碼的位置),造成程式異常。

間接分支是幽灵漏洞的攻擊表面之一。為了緩解此攻擊,GCC 8.1導入了以下選項:-mindirect-branch=, -mfunction-return= and -mindirect-branch-register.[1][nb 1]

組合語言範例

[编辑]
MSP430:   br r15
SPARC:   jmpl %o7
MIPS架構:    jr $ra
x86(AT&T語法):      jmp *%eax
x86(Intel語法):      jmp eax
ARM:     BX r0, mov pc, r2
Itanium(x86系列):    br.ret.sptk.few rp
6502:    jmp ($0DEA)
65C816英语65C816 jsr ($0DEA,X)
6809英语6809 jmp [$0DEA], jmp B,X, jmp [B,X]
6800 jmp 0,X
Z80 jp (hl)
英特爾8051 jmp @A+DPTR
Intel 8080 pchl
IBM System z bcr cond,r1[2]
PDP-11 jmp @R5
RISC-V: jalr x0, 0(x1)

相關條目

[编辑]

註解

[编辑]
  1. ^ Consult also the RETPOLINE=y feature added in Linux kernel 4.14.14/4.9.77/4.4.112. 也可以參考:幽灵漏洞

參考資料

[编辑]
  1. ^ Larabel, Michael. Spectre Mitigation Added To GCC 8, Seeking Backport To GCC 7. 2018-01-14 [2018-01-19]. (原始内容存档于2018-01-20). 
  2. ^ z/Architecture - Principles of Operation 4. IBM. May 2004 [1990] [2018-05-26]. SA22-7832-03. (原始内容存档于2016-03-04).