ARM 汇编指令:BX

ARM 汇编指令:BX

本文来自于我关于 ARM 汇编指令系列文章。欢迎阅读、点评与交流~
1、汇编指令在不同架构中的联系与区别
2、ARM 汇编指令:MOV
3、ARM 汇编指令:LDR
4、ARM 汇编指令:STR
5、ARM 汇编指令:MRS 和 MSR
6、ARM 汇编指令:ORRS
7、ARM 汇编指令:BEQ
8、ARM 汇编指令:TST
9、ARM 汇编指令:B
10、ARM 汇编指令:BX

核心定义

BXBranch and eXchange 的缩写,意为 分支并切换指令集。它是 ARM 指令集中用于实现子程序调用返回、以及在不同指令集状态(ARM 状态和 Thumb 状态)之间切换的关键指令。

基本语法

assembly 复制代码
BX{<cond>} <Rm>
  • {} :可选的条件码,例如 EQ, NE, GT 等。用于条件执行。
  • :一个通用寄存器,其内容包含了目标地址 目标指令集状态信息。

工作原理

BX 指令执行两个核心操作:

  1. 分支(跳转):将程序计数器 PC 设置为目标地址。
  2. 切换指令集:根据目标地址最低有效位(LSB)的值,决定切换到 ARM 状态还是 Thumb 状态。
关键:目标地址的最低有效位(LSB, Least Significant Bit)

在 ARM 体系结构中,指令必须是字对齐(ARM状态,4字节对齐)或半字对齐(Thumb状态,2字节对齐)。因此,地址的 LSB 在正常执行时总是 0。ARM 巧妙地利用了这个"闲置"的位来编码指令集状态:

  • 如果 Rm 的 LSB = 0 :处理器在跳转到目标地址(Rm & 0xFFFFFFFE)后,切换到(或保持)ARM 状态。此时 PC 的 bit[0] 会被硬件忽略。
  • 如果 Rm 的 LSB = 1 :处理器在跳转到目标地址(Rm & 0xFFFFFFFE)后,切换到(或保持)Thumb 状态

重要 :BX 在执行跳转前,会自动清除 Rm 的 bit[0] ,以确保目标地址是正确对齐的。你提供的 Rm 值需要你自己确保 bit[0] 正确设置了状态。

主要用途

  1. 子程序返回(最常见)

    在 ARM 中,BL (Branch with Link) 指令用于调用子程序,它会将返回地址(PC+4PC+2)保存到链接寄存器 LR (R14) 中。在子程序结束时,通常用 BX LR 返回。

    • 调用时,BL 会自动将 LR 的 LSB 设置为当前指令集状态(CPSR 的 T 位),保证返回时能正确切换回原来的状态。
    assembly 复制代码
    ; 在主程序(ARM状态)中调用
    BL      thumb_function  ; 调用Thumb子程序,LR的LSB被自动设为1
    ...
    
    thumb_function:
        .thumb              ; 声明为Thumb代码
        ...                 ; 执行操作
        BX      LR          ; 返回!LSB=1,所以切换回ARM状态
  2. 在 ARM 和 Thumb 状态间切换(常见于Cortex-A系列)

    当需要从一段 ARM 代码跳转到 Thumb 代码时,必须使用 BX 或类似的指令(如 BLX)来进行切换。

    assembly 复制代码
    ; 从 ARM 状态切换到 Thumb 状态
    LDR     R0, =thumb_code_label+1 ; +1 至关重要!确保目标地址LSB=1
    BX      R0                      ; 跳转并切换到Thumb状态
    
    .thumb
    thumb_code_label:
        ... ; 这里是Thumb指令
  3. 实现函数指针调用

    由于 BX 可以跳转到任意寄存器指定的地址,它非常适合用于调用通过函数指针指定的函数,这在C语言中很常见。

    c 复制代码
    // C 代码
    void (*func_ptr)(void) = some_function;
    func_ptr(); // 编译器通常会生成 BX Rm 指令

与相关指令的对比

指令 全称 功能 链接 (LR) 状态切换
BX Branch and eXchange 跳转到寄存器指定地址 不保存返回地址 根据目标地址 LSB 切换
BLX Branch with Link and eXchange 跳转到寄存器/立即数地址 保存返回地址到 LR 根据目标地址 LSB 或固定切换
B Branch 跳转到立即数地址 不保存 不切换,保持当前状态
BL Branch with Link 跳转到立即数地址 保存 不切换,保持当前状态

示例

assembly 复制代码
    .syntax unified    @ 统一汇编语法
    .arch armv7-m      @ 指定架构为Cortex-M(只支持Thumb)

    .thumb             @ 以下为Thumb代码
    .global _start
_start:
    MOVS    R0, #10        @ Thumb指令
    ADDS    R0, R0, #5

    @ 假设我们需要调用一个已知地址的ARM函数(在Cortex-A上)
    LDR     R1, =arm_function_addr @ 加载ARM函数地址
    BX      R1                    @ 跳转并切换到ARM状态(假设R1的LSB=0)

    @ 返回后会切换回Thumb状态
    ...

    .align 2
    .arm                        @ 声明为ARM代码
arm_function_addr:
    MOV     R2, #0x1000         @ ARM指令
    ...
    BX      LR                  @ 返回到调用者,并切换回Thumb状态(因为LR的LSB=1)

总结

BX 是 ARM 体系结构中的一个智能跳转指令 。它的核心价值在于将控制流转移(跳转)和指令集状态切换 完美地结合在一起,通过目标地址的最低有效位(LSB)来编码状态信息 。这使得 ARM/Thumb 混合编程、高效的子程序返回和动态函数调用成为可能,是 ARM 灵活性的一个重要体现。在编写需要状态切换的代码或进行子程序返回时,BX LR 是最标准、最安全的方式。

相关推荐
小草cys8 小时前
【有问题未解决】Ubuntu arm版的桌面分辨率修改
linux·arm开发·ubuntu
爱编程的小吴17 小时前
通义灵码输出软件设计文档实例1
arm开发·ai写作
szxinmai主板定制专家20 小时前
基于 PC 的控制技术+ethercat+linux实时系统,助力追踪标签规模化生产,支持国产化
arm开发·人工智能·嵌入式硬件·yolo·fpga开发
前端菜鸟日常21 小时前
鸿蒙开发实战:100 个项目疑难杂症汇编
汇编·华为·harmonyos
切糕师学AI21 小时前
ARM 汇编器中的伪指令(Assembler Directives)
开发语言·arm开发·c#
陌上花开缓缓归以1 天前
OPENWRT 端口link问题
linux·arm开发
VekiSon1 天前
Linux内核驱动——Ubuntu 网络启动环境配置与操作
linux·arm开发·嵌入式硬件·ubuntu
ONLYOFFICE1 天前
如何在 Fedora 43 ARM 架构设备上安装 ONLYOFFICE 桌面编辑器
arm开发·编辑器
陌上花开缓缓归以1 天前
insmod 报错问题定位纪要
linux·arm开发
188号安全攻城狮2 天前
【PWN】HappyNewYearCTF_9_ret2syscall
linux·汇编·安全·网络安全·系统安全