7. คำสั่งแตกสาขา¶
คำสั่งเหล่านี้ทำให้การดำเนินการกระโดดไปยังตำแหน่งเป้าหมายซึ่งมักระบุด้วย label (ดู label() assembler directive) คำสั่งแตกสาขาแบบมีเงื่อนไขและคำสั่ง it และ ite ตรวจสอบ Application Program Status Register (APSR) ค่าสถานะ N (ลบ), Z (ศูนย์), C (carry) และ V (overflow) เพื่อกำหนดว่าควรดำเนินการแตกสาขาหรือไม่
คำสั่ง assembler ส่วนใหญ่ที่เปิดเผย (รวมถึงการดำเนินการย้าย) จะตั้งค่าสถานะ แต่มีคำสั่งเปรียบเทียบที่ชัดเจนเพื่อให้สามารถทดสอบค่าได้
รายละเอียดเพิ่มเติมเกี่ยวกับความหมายของค่าสถานะเงื่อนไขมีอยู่ในส่วน comparison instructions
7.1. ข้อตกลงในเอกสาร¶
สัญลักษณ์: Rm หมายถึงรีจิสเตอร์ ARM R0-R15 LABEL หมายถึง label ที่กำหนดด้วย assembler directive label() <condition> ระบุตัวระบุเงื่อนไขอย่างใดอย่างหนึ่งต่อไปนี้:
eq เท่ากับ (ผลลัพธ์เป็นศูนย์)
ne ไม่เท่ากัน
cs Carry ถูกตั้ง
cc Carry ถูกล้าง
mi ลบ (negative)
pl บวก (positive)
vs Overflow ถูกตั้ง
vc Overflow ถูกล้าง
hi > (การเปรียบเทียบไม่มีเครื่องหมาย)
ls <= (การเปรียบเทียบไม่มีเครื่องหมาย)
ge >= (การเปรียบเทียบมีเครื่องหมาย)
lt < (การเปรียบเทียบมีเครื่องหมาย)
gt > (การเปรียบเทียบมีเครื่องหมาย)
le <= (การเปรียบเทียบมีเครื่องหมาย)
7.2. แตกสาขาไปยัง label¶
b(LABEL) แตกสาขาแบบไม่มีเงื่อนไข
beq(LABEL) แตกสาขาหากเท่ากัน
bne(LABEL) แตกสาขาหากไม่เท่ากัน
bge(LABEL) แตกสาขาหากมากกว่าหรือเท่ากับ
bgt(LABEL) แตกสาขาหากมากกว่า
blt(LABEL) แตกสาขาหากน้อยกว่า (<) (มีเครื่องหมาย)
ble(LABEL) แตกสาขาหากน้อยกว่าหรือเท่ากับ (<=) (มีเครื่องหมาย)
bcs(LABEL) แตกสาขาหาก carry flag ถูกตั้ง
bcc(LABEL) แตกสาขาหาก carry flag ถูกล้าง
bmi(LABEL) แตกสาขาหากเป็นลบ
bpl(LABEL) แตกสาขาหากเป็นบวก
bvs(LABEL) แตกสาขาหาก overflow flag ถูกตั้ง
bvc(LABEL) แตกสาขาหาก overflow flag ถูกล้าง
bhi(LABEL) แตกสาขาหากมากกว่า (ไม่มีเครื่องหมาย)
bls(LABEL) แตกสาขาหากน้อยกว่าหรือเท่ากัน (ไม่มีเครื่องหมาย)
7.3. การแตกสาขาระยะไกล¶
โค้ดที่สร้างโดยคำสั่งแตกสาขาที่แสดงข้างต้นใช้ความกว้างบิตคงที่เพื่อระบุปลายทางการแตกสาขา ซึ่งเป็น PC-relative ดังนั้นในโปรแกรมขนาดใหญ่ที่คำสั่งแตกสาขาอยู่ห่างจากปลายทาง assembler จะสร้างข้อผิดพลาด "branch not in range" ซึ่งสามารถเอาชนะได้ด้วยตัวแปร "wide" เช่น
beq_w(LABEL) แตกสาขาระยะไกลหากเท่ากัน
การแตกสาขาแบบ wide ใช้ 4 ไบต์ในการเข้ารหัสคำสั่ง (เทียบกับ 2 ไบต์สำหรับคำสั่งแตกสาขามาตรฐาน)
7.4. Subroutine (ฟังก์ชัน)¶
เมื่อเข้าสู่ subroutine โปรเซสเซอร์จะเก็บที่อยู่ผู้ส่งคืนไว้ในรีจิสเตอร์ r14 หรือที่รู้จักกันในชื่อ link register (lr) การส่งคืนไปยังคำสั่งหลังจากการเรียก subroutine ทำได้โดยการอัปเดต program counter (r15 หรือ pc) จาก link register กระบวนการนี้จัดการโดยคำสั่งต่อไปนี้
bl(LABEL)
โอนการดำเนินการไปยังคำสั่งหลังจาก LABEL โดยเก็บที่อยู่ผู้ส่งคืนไว้ใน link register (r14)
bx(Rm) แตกสาขาไปยังที่อยู่ที่ระบุโดย Rm
โดยทั่วไป bx(lr) จะถูกออกเพื่อส่งคืนจาก subroutine สำหรับ subroutine ที่ซ้อนกัน link register ของขอบเขตภายนอกต้องถูกบันทึก (โดยปกติบน stack) ก่อนดำเนินการเรียก subroutine ภายใน