汇编之分支跳转指令

  • 顺序执行:硬件自动修改PC寄存器, PC = PC+4
  • 在ARM中有两种方式可以跳转:
    • 直接向PC寄存器写入目标地址值
z80 复制代码
mov pc, #0xff000000 @跳转到0xff000000的位置去执行
复制代码
- 专门的跳转指令
    * B/BL
    * BX/BLX

B/BL

z80 复制代码
b{l}{cond} <target>
  l, 自动将下一条指令的地址保存到LR寄存器, 子程序调用的一个基本但常用的手段
  cond, 条件码
  target,目标地址
z80 复制代码
/*
 * 比较两个寄存器的值,若r0 < r1则交换它们,最后执行无意义的加法并进入死循环
 */
.text               @ 声明代码段,后续内容为可执行指令
.global _start      @ 将_start符号声明为全局可见,作为程序入口点

_start:             @ 程序入口标签
  mov r0, #10       @ 将立即数10加载到寄存器r0中 (r0 = 10)
  mov r1, #20       @ 将立即数20加载到寄存器r1中 (r1 = 20)
  cmp r0, r1        @ 比较r0和r1的值 (执行 r0 - r1,仅更新状态寄存器CPSR)
  bllt swap         @ 条件分支指令:若r0 < r1 (LT=Less Than),则跳转到swap标签,同时将返回地址存入lr寄存器
  add r5, r6, r7    @ 执行加法操作:r5 = r6 + r7 (注:r6/r7未初始化,值为随机数)
  b stop            @ 无条件跳转到stop标签

swap:               @ 交换r0和r1值的函数标签
  mov r2, r0        @ 临时保存r0的值到r2 (r2 = r0)
  mov r0, r1        @ 将r1的值赋给r0 (r0 = r1)
  mov r1, r2        @ 将临时保存的r0值(r2)赋给r1 (r1 = r2)
  mov pc, lr        @ 将链接寄存器lr的值赋给程序计数器pc,实现函数返回

stop:               @ 程序终止标签
  b .               @ 无条件跳转到当前地址(死循环),使程序暂停在此处
.end                @ 汇编程序结束标记
  • b/bl 指定后面直接给定了要跳转的地址, 包括地址在内的所有信息会被翻译为一条32bit的机器指令,注定跳转范围受限:±32M

BX/BLX

  • X, 带状态切换的分支跳转指令
z80 复制代码
b{l}x{cond} <Rm>
  Rm,通用寄存器, 存放的是要跳转的地址
  • 跳转范围不受限 0~4G随便跳
z80 复制代码
/*
* 程序功能:比较R0和R1的值,若R0 < R1则交换两者,最后原地死循环
*/
.text                   @ 声明代码段(存放可执行指令)
.global _start          @ 将_start声明为全局符号,作为程序入口

_start:                     @ 程序入口标签
    mov     r0, #10         @ 初始化R0寄存器为立即数10(第一个比较数)
    mov     r1, #20         @ 初始化R1寄存器为立即数20(第二个比较数)
    
    cmp     r0, r1          @ 比较指令:执行R0 - R1,仅更新CPSR状态位(不保存结果)
                            @ 会影响的标志位:N(负)、Z(零)、C(进位)、V(溢出)
    
    blcc    swap            @ 带链接条件跳转:cc(Carry Clear,C=0)即无进位,对应R0 < R1
                            @ 若R0 < R1则跳转到swap子程序,同时将返回地址(当前指令下一条)存入LR(R14)
    
    add     r3, r4, r5      @ 加法指令:R3 = R4 + R5(注:R4/R5未初始化,结果为随机值)
    b       .               @ 无条件跳转到当前地址(.表示当前PC值),实现原地死循环

swap:                       @ 子程序:交换R0和R1的值
    mov     r2, r0          @ 第一步:将R0的值暂存到R2(临时寄存器)
    mov     r0, r1          @ 第二步:将R1的值赋值给R0
    mov     r1, r2          @ 第三步:将R2中暂存的原R0值赋值给R1,完成交换
    ; mov   pc, lr          @ 传统返回方式:直接将LR的值写入PC,等价跳转(已注释,推荐用bx lr)
    bx      lr              @ 带状态切换的返回:将LR的值写入PC,返回调用处
                            @ bx支持ARM/Thumb指令集切换,兼容性更强,是推荐的返回方式

    .end                    @ 汇编结束标记(告诉汇编器程序结束)
  • 练习:求1到10的累加和结果保存到r0
z80 复制代码
.text
.global _start @将_start声明为全局的
_start:
  mov r0, #0
  mov r1, #10 @循环次数
loop:
  add r0, r0, r1
  sub r1, r1, #1
  cmp r1, #0
  bne loop
  b .
.end
  • 练习:求1到10的累加和结果保存到r0
z80 复制代码
.text
.global _start @将_start声明为全局的
_start:mov r0, #8
  mov r1, #36
loop:
  cmp r0, r1
  sublt r1, r1, r0
  subgt r0, r0, r1
  bne loop
  b .
.end
相关推荐
疯狂打码的少年15 小时前
【程序语言与编译】程序设计语言分类(机器/汇编/高级)
汇编·笔记
JAMSAN093017 小时前
16.0% 高增长!全球异构计算架构服务市场扩容态势
汇编·人工智能·架构
暮云星影2 天前
个人总结 docker搭建私人照片云相册Immich
docker·容器·arm
iCxhust2 天前
8086汇编 word ptr
汇编·单片机·嵌入式硬件·微机原理·8088单板机
大阳1233 天前
ARM.9(RGBLCD,PWM)
c语言·开发语言·汇编·单片机·嵌入式硬件·pwm·rgblcd
凉、介4 天前
深入理解 ARMv8-A|Application Binary Interface (ABI)
c语言·笔记·学习·嵌入式·arm
2301_789015624 天前
Linux基础开发工具一:软件包管理器、vim编辑器
linux·服务器·c语言·汇编·c++·编辑器·vim
是星辰吖~4 天前
X86反汇编_深度学习_基础二叉树
汇编
iCxhust5 天前
汇编返回指令ret iret retf区别
汇编·微机原理·8088单板机
怣疯knight5 天前
ida里打印python版本
汇编