7. 分支指令

這些指令會使執行跳轉至通常由標籤指定的目標位置(請參閱 label() 組語指示詞)。條件分支以及 itite 指令會測試應用程式狀態暫存器(APSR)的 N(負)、Z(零)、C(進位)與 V(溢位)旗標,以判斷是否應執行該分支。

大多數已公開的組語指令(包括移動運算)都會設定旗標,但仍有專門的比較指令可供測試值。

關於條件旗標含義的更多細節,請參閱 comparison instructions 章節。

7.1. 文件慣例

標記法:Rm 表示 ARM 暫存器 R0-R15。LABEL 表示以 label() 組語指示詞定義的標籤。<condition> 表示下列其中一個條件指定符:

  • eq 等於(結果為零)

  • ne 不等於

  • cs 進位被設定

  • cc 進位被清除

  • mi 負(negative)

  • pl 正(positive)

  • 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 中,r14 也稱為連結暫存器(lr)。返回至子常式呼叫之後的指令,是藉由從連結暫存器更新程式計數器(r15 或 pc)來完成的。此程序由下列指令處理。

  • bl(LABEL)

將執行轉移至 LABEL 之後的指令,並將返回位址儲存在連結暫存器(r14)中。

  • bx(Rm) 分支至 Rm 所指定的位址。

通常會發出 bx(lr) 以從子常式返回。對於巢狀子常式,必須在進行內層子常式呼叫之前,先將外層範圍的連結暫存器儲存起來(通常存於堆疊上)。