• ARM 汇编指令集——汇编中三种符号(汇编指令、伪指令、伪操作)、汇编基本格式、数据操作指令、跳转指令、特殊功能寄存器操作指令、内存操作指令、混合编程


    目录

    一、汇编中三种符号(汇编指令、伪指令、伪操作)

    二、汇编基本格式

    三、数据操作指令

    3.1 数据搬移指令mov/mvn

    ① 示例

    ② 立即数

    3.2 移位操作指令lsl/lsr/asr/ror

    示例

    3.3 位运算操作指令and/orr/eor/bic

    ① 示例1

    ② 示例2

    3.4 算数运算操作指令add/adc/sub/sbc/mul

    ① 实现两个64位数相加

    ② 实现两个64位数相减

    ③ 乘法指令

    3.5 比较指令cmp

    ① 条件指令

    ② 示例

    四、跳转指令

    ① 练习

    五、特殊功能寄存器操作指令

    六、内存操作指令

    6.1 单寄存器操作指令

    ① 读写代码练习

    ② 特殊读写格式

    ③ 验证keil软件存储方式

    6.2 多寄存器操作指令

    ① 练习

    6.3 栈指针操作指令

    ① 满压栈、空增栈压入数据过程

    ② 练习代码1

    ③ 栈使用场合1

    ④ 栈使用场合2

    七、混合编程

    7.1 汇编调用C

    汇编文件编写

    C函数编写

    7.2 C调用汇编

    汇编启动文件编写:start.s文件

    C语言main函数入口:main.c文件

    汇编实现加法函数编写:add.s文件

    7.3 内联汇编

    八、总结


    一、汇编中三种符号(汇编指令、伪指令、伪操作)

    二、汇编基本格式

    三、数据操作指令

    3.1 数据搬移指令mov/mvn

    ① 示例

    ② 立即数

    1. 0xff000000 =====>判断的数
    2. 1111 1111 0000 0000 0000 0000 0000 0000 =====>判断的数
    3. 0000 0000 0000 0000 0000 0000 1111 1111 =====>找到0xff这个数 =====> 循环右移8
    4. 0xf0000000 =====>判断的数
    5. 1111 0000 0000 0000 0000 0000 0000 0000 =====>判断的数
    6. 0000 0000 0000 0000 0000 0000 0000 1111 =====>找到0xf这个数 =====> 循环右移4
    7. 0xf000000f =====>判断的数
    8. 1111 0000 0000 0000 0000 0000 0000 1111 =====>判断的数
    9. 0000 0000 0000 0000 0000 0000 1111 1111 =====>找到0xff这个数 =====> 循环右移4
    10. 0x1FE00000=====>判断的数
    11. 0001 1111 1110 0000 0000 0000 0000 0000 =====>判断的数
    12. 0000 0000 0000 0000 0000 0000 1111 1111 =====>找到0xff这个数 =====> 循环右移11
    13. 0x1F800000=====>判断的数
    14. 0001 1111 1000 0000 0000 0000 0000 0000 =====>判断的数
    15. 0000 0000 0000 0000 0000 0000 0111 1110 =====>找到0x7E这个数 =====> 循环右移10

    3.2 移位操作指令lsl/lsr/asr/ror

    示例

    1. mov r0,#0xff
    2. @ 1.将r0寄存器中的值,逻辑左移4位,赋值给目标寄存器r1,值
    3. lsl r1,r0,#0x4 @ r1 = r0 << 4 = 0xff0
    4. @ 0000 0000 0000 0000 0000 0000 1111 1111
    5. @ 0000 0000 0000 0000 0000 1111 1111 0000
    6. @ 2.将r1寄存器中的值,逻辑右移4位,赋值给目标寄存器r2,值 r2 = r1 >> 4
    7. lsr r2,r1,#0x4 @ r2 = r1 >> 4 = 0xff
    8. @ 0000 0000 0000 0000 0000 1111 1111 0000
    9. @ 0000 0000 0000 0000 0000 0000 1111 1111
    10. @ 3.将r2寄存器中的值,循环右移4位,赋值给目标寄存器r3,值
    11. ror r3,r2,#0x4 @ r3 = 0xf000000f
    12. @ 0000 0000 0000 0000 0000 0000 1111 1111
    13. @ 1111 0000 0000 0000 0000 0000 0000 1111
    14. ldr r4,=0x800000ff
    15. @ 4.将r4寄存器中的值,算数右移4位,赋值给目标寄存器r5,值
    16. asr r5,r4,#0x4 @ r5 = 0xf800000f
    17. @ 1000 0000 0000 0000 0000 0000 1111 1111
    18. @ 1111 1000 0000 0000 0000 0000 0000 1111

    3.3 位运算操作指令and/orr/eor/bic

    ① 示例1

    ② 示例2

    3.4 算数运算操作指令add/adc/sub/sbc/mul

    ① 实现两个64位数相加

    1. @第一个64位数:高32位用r0表示0x3 低32位用r1表示0xffffffff
    2. @第二个64位数:高32位用r2表示0x4 低32位用r3表示0x1
    3. @实现两个64位数相加:高32位相加r4,低32位相加r5
    4. ldr r0,=0x3
    5. ldr r1,=0xffffffff
    6. ldr r2,=0x4
    7. ldr r3,=0x1
    8. adds r5,r1,r3 @ r5 = r1 + r3 = 0xffffffff + 0x1 = 0x0 ===> add 影响CPSR寄存器的C位
    9. adc r4,r0,r2 @ r4 = r0 + r2 = 0x3 + 0x4 + C = 0x8 ===> adc

    ② 实现两个64位数相减

    1. @第一个64位数:高32位用r0表示0x7 低32位用r1表示0x4
    2. @第二个64位数:高32位用r2表示0x4 低32位用r3表示0x5
    3. @实现两个64位数相减法:高32位相加r4,低32位相加r5
    4. ldr r0,=0x7
    5. ldr r1,=0x4
    6. ldr r2,=0x4
    7. ldr r3,=0x5
    8. subs r5,r1,r3 @ r5 = r1 - r3 = 0x4 - 0x5 = 0xffffffff ===> sub 影响CPSR寄存器的C位
    9. sbc r4,r0,r2 @ r4 = r0 - r2 = 0x7 - 0x4 - !C = 0x2 ===> sbc

    ③ 乘法指令

    3.5 比较指令cmp

    ① 条件指令

    ② 示例

    四、跳转指令

    ① 练习

    五、特殊功能寄存器操作指令

    六、内存操作指令

    6.1 单寄存器操作指令

    ① 读写代码练习

    ② 特殊读写格式

    1. ldr r0,=0x40000800 @ 准备一块地址空间
    2. ldr r1,=0x11111111 @ r1 = 0x11111111
    3. ldr r2,=0x22222222 @ r1 = 0x22222222
    4. ldr r3,=0x33333333 @ r1 = 0x33333333
    5. @仿真时,思考1)寄存器写到哪一块地址空间中,2)观察r0寄存器中的值变化
    6. @将r1寄存器中的值,写到r0+4地址空间中,r0寄存器中的值没有发生变化
    7. @ [0x40000804] = 0x11111111 r0 = 0x40000800
    8. str r1,[r0,#4]
    9. @将r2寄存器中的值,写到r0地址空间中,r0寄存器中的值+4
    10. @ [0x40000800] = 0x22222222 r0 = 0x40000804
    11. str r2,[r0],#4
    12. @将r3寄存器中的值,写到r0+4地址空间中,r0寄存器中的值+4
    13. @ [0x40000808] = 0x33333333 r0 = 0x40000808
    14. str r3,[r0,#4]!

    ③ 验证keil软件存储方式

    6.2 多寄存器操作指令

    ① 练习

    6.3 栈指针操作指令

    ① 满压栈、空增栈压入数据过程

    ② 练习代码1

    ③ 栈使用场合1

    1. ldr sp,=0x40000800 @ 准备一块地址空间
    2. mov r0,#0x1 @ r0 = 0x1
    3. mov r1,#0x2 @ r1 = 0x2
    4. bl add1_func @ 跳转到add1_func函数
    5. add r0,r0,r1 @ r0 = r0 + r1 = 0x3
    6. b stop
    7. add1_func:
    8. @ 压栈保存现场 r0 = 0x1 r1 = 0x2
    9. stmfd sp!,{r0-r1}
    10. mov r0,#0x3 @ r0 = 0x3
    11. mov r1,#0x4 @ r1 = 0x4
    12. add r0,r0,r1 @ r0 = r0 + r1 = 0x7
    13. @ 出栈保存现场 r0 = 0x1 r1 = 0x2
    14. ldmfd sp!,{r0-r1}
    15. mov pc,lr @ pc = lr

    ④ 栈使用场合2

    1. _start: @指定汇编中函数入口
    2. ldr sp,=0x40000800 @ 准备一块地址空间
    3. mov r0,#0x1 @ r0 = 0x1
    4. mov r1,#0x2 @ r1 = 0x2
    5. bl add1_func @ 跳转到add1_func函数,保存函数返回地址到LR寄存器中
    6. add r0,r0,r1 @ r0 = r0 + r1 = 0x3
    7. b stop
    8. add1_func:
    9. @ 压栈保存现场 r0 = 0x1 r1 = 0x2
    10. stmfd sp!,{r0-r1,lr}
    11. mov r0,#0x3 @ r0 = 0x3
    12. mov r1,#0x4 @ r1 = 0x4
    13. bl add2_func @跳转到add2_func函数,保存函数返回地址到LR寄存器中
    14. add r0,r0,r1 @ r0 = r0 + r1 = 0x7
    15. @ 出栈保存现场 r0 = 0x1 r1 = 0x2
    16. ldmfd sp!,{r0-r1,pc}
    17. add2_func:
    18. @ 压栈保存现场 r0 = 0x3 r1 = 0x4
    19. stmfd sp!,{r0-r1}
    20. mov r0,#0x5 @ r0 = 0x5
    21. mov r1,#0x6 @ r1 = 0x6
    22. add r0,r0,r1 @ r0 = r0 + r1 = 0xB
    23. @ 出栈保存现场 r0 = 0x3 r1 = 0x4
    24. ldmfd sp!,{r0-r1}
    25. mov pc,lr

    七、混合编程

    7.1 汇编调用C

    汇编文件编写

    1. ldr sp,=0x40000800 @ 初始化栈指针
    2. mov r0,#0x1
    3. mov r1,#0x2
    4. mov r2,#0x3
    5. mov r3,#0x4
    6. bl add_func

    C函数编写

    1. int add_func(int a,int b,int c,int d)
    2. {
    3. return (a+b+c+d);
    4. }

    7.2 C调用汇编

    汇编启动文件编写:start.s文件

    1. ldr sp,=0x40000800 @ 初始栈指针
    2. b main @ 跳转到C函数入口

    C语言main函数入口:main.c文件

    1. int sum1 = 0;
    2. int add1_func(int a,int b,int c,int d);
    3. int main()
    4. {
    5. sum1 = add1_func(1,2,3,4);
    6. while(1);
    7. return 0;
    8. }

    汇编实现加法函数编写:add.s文件

    1. @ 实现r0-r3相加,并且通过r0返回
    2. .text
    3. .global add1_func
    4. add1_func:
    5. add r0,r0,r1
    6. add r0,r0,r2
    7. add r0,r0,r3
    8. mov pc,lr
    9. .end

    7.3 内联汇编

    八、总结

  • 相关阅读:
    Effective Java 第二版第11章 序列化
    【算法】一类支持向量机OC-SVM(2)
    码科速送同城跑腿小程序 v3.2.8+用户端+接单端 安装测试教程
    学生管理系统(Java版)
    如何通过企业培训考试系统实现持续学习和发展
    Ubuntu下查看资源占用情况
    ThinkPHP文件上传验证器
    元宇宙时代到来,Soul张璐团队如何打造全新社交体验?
    项目讲解说明
    2022年《一生一系统作业》python练习题
  • 原文地址:https://blog.csdn.net/Smallxu_/article/details/132918332