ARM裸机启动代码中beq指令操作码异常疑问求解
ARM crt0.o中beq指令的工作原理与跳转条件
首先要明确:你混淆了ARM架构与x86架构的汇编指令规则。你引用的《Using as》手册中关于beq展开为jeq、jne的描述是x86架构的规则,和ARM完全无关,这是核心误解点。
逐行解析给定的反汇编代码
00000000 <_stack_init>: 0: e10f4000 mrs r4, CPSR 4: e314000f tst r4, #15 8: 0a00001c beq 80 <_stack_init+0x80>
mrs r4, CPSR:将ARM处理器的程序状态寄存器(CPSR)的值读取到r4寄存器。CPSR的低5位(M[4:0])用于标识当前处理器模式。tst r4, #15:对r4和立即数15(二进制0b1111)执行按位与操作,结果仅影响标志位Z(零标志):- 若按位与结果为0,Z标志置1;
- 若结果非0,Z标志置0。
这里本质是检查CPSR的低4位(M[3:0])是否全为0。
beq 80 <_stack_init+0x80>:这是ARM原生的条件跳转指令,beq即Branch Equal,当Z标志为1时触发跳转:- 指令编码
0a00001c拆解:高4位0000是EQ条件码(对应Z=1),后续位是B指令操作码,最后24位是有符号偏移量。 - 跳转地址计算:偏移量
0x1c左移2位(ARM指令4字节对齐,偏移以字为单位)得到0x70,加上当前指令地址+8(ARM流水线特性,执行当前指令时PC值为当前地址+8),即0x8 + 8 + 0x70 = 0x80,和反汇编标注的目标地址一致。
- 指令编码
跳转条件与实际意义
当tst r4, #15的结果为0(Z=1)时,说明CPSR的低4位全为0,对应ARM处理器的用户模式(用户模式的M[4:0]是10000,低4位为0000)。这段代码的逻辑是:如果当前处于用户模式,则跳转到0x80地址执行特定的栈初始化逻辑;若处于其他特权模式,则继续执行后续代码。
关于你的手册内容误解
ARM架构下的beq是原生单条条件跳转指令,不存在展开为多条指令的情况。只有当跳转距离超过ARM B指令的最大范围(±32MB,由24位偏移左移2位决定)时,才会采用“加载目标地址到寄存器+bx跳转”的方式,但你的示例中跳转距离仅为0x78字节,完全在B指令的范围内,因此直接生成了单条ARM条件跳转指令。
内容的提问来源于stack exchange,提问作者AJM
相关产品推荐
相关产品推荐

