7. Branch-instructies#
Deze zorgen ervoor dat de uitvoering springt naar een doellocatie die doorgaans wordt gespecificeerd door een label (zie de label() assembler-directive). Voorwaardelijke branches en de it- en ite-instructies testen de N- (negatief), Z- (nul), C- (carry) en V- (overflow) vlaggen van het Application Program Status Register (APSR) om te bepalen of de branch moet worden uitgevoerd.
De meeste blootgestelde assembler-instructies (waaronder move-operaties) zetten de vlaggen, maar er zijn expliciete vergelijkingsinstructies om waarden te kunnen testen.
Verdere details over de betekenis van de conditievlaggen worden gegeven in de sectie vergelijkingsinstructies.
7.1. Documentconventies#
Notatie: Rm duidt de ARM-registers R0-R15 aan. LABEL duidt een label aan dat is gedefinieerd met de label() assembler-directive. <condition> geeft een van de volgende conditie-specificeerders aan:
eq Gelijk aan (resultaat was nul)
ne Niet gelijk
cs Carry gezet
cc Carry gewist
mi Min (negatief)
pl Plus (positief)
vs Overflow gezet
vc Overflow gewist
hi > (unsigned vergelijking)
ls <= (unsigned vergelijking)
ge >= (signed vergelijking)
lt < (signed vergelijking)
gt > (signed vergelijking)
le <= (signed vergelijking)
7.2. Branch naar label#
b(LABEL) Onvoorwaardelijke branch
beq(LABEL) branch indien gelijk
bne(LABEL) branch indien niet gelijk
bge(LABEL) branch indien groter dan of gelijk aan
bgt(LABEL) branch indien groter dan
blt(LABEL) branch indien kleiner dan (<) (signed)
ble(LABEL) branch indien kleiner dan of gelijk aan (<=) (signed)
bcs(LABEL) branch indien de carry-vlag gezet is
bcc(LABEL) branch indien de carry-vlag gewist is
bmi(LABEL) branch indien negatief
bpl(LABEL) branch indien positief
bvs(LABEL) branch indien de overflow-vlag gezet is
bvc(LABEL) branch indien de overflow-vlag gewist is
bhi(LABEL) branch indien hoger (unsigned)
bls(LABEL) branch indien lager of gelijk (unsigned)
7.3. Lange branches#
De code die door de hierboven genoemde branch-instructies wordt geproduceerd, gebruikt een vaste bitbreedte om de branch-bestemming te specificeren, die PC-relatief is. Bijgevolg zal de assembler in lange programma’s, waar de branch-instructie ver van zijn bestemming verwijderd is, een “branch not in range”-fout produceren. Dit kan worden omzeild met de “wide”-varianten zoals
beq_w(LABEL) lange branch indien gelijk
Wide-branches gebruiken 4 bytes om de instructie te coderen (vergeleken met 2 bytes voor standaard branch-instructies).
7.4. Subroutines (functies)#
Bij het binnengaan van een subroutine slaat de processor het retouradres op in register r14, ook wel bekend als het link-register (lr). Het terugkeren naar de instructie na de subroutine-aanroep gebeurt door de program counter (r15 of pc) bij te werken vanuit het link-register. Dit proces wordt afgehandeld door de volgende instructies.
bl(LABEL)
Draag de uitvoering over aan de instructie na LABEL en sla het retouradres op in het link-register (r14).
bx(Rm) Branch naar het adres dat door Rm wordt gespecificeerd.
Doorgaans wordt bx(lr) uitgevoerd om terug te keren uit een subroutine. Voor geneste subroutines moet het link-register van de buitenste scopes (meestal op de stack) worden opgeslagen voordat aanroepen van binnenste subroutines worden uitgevoerd.