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 ภายใน