码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 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 内联汇编

    八、总结

  • 相关阅读:
    SVN安装教程详解:快速掌握SVN的安装和使用方法
    Windows环境-Redis数据库部署
    淘宝店铺上新图片上传获取请求方法
    【Go语言】Go语言中的切片
    氟化钙光学窗口保护镜片 光学元件红外测温窗口保护片
    C++运动会分数统计系统
    文件上传漏洞靶场前十关
    300PLCmpi转以太网通过MPI-ETH-XD1.0在发食品发酵控制系统中的应用
    【网络安全小课堂】网络安全相关名词解释
    实验(三):单片机I/O口实验-模拟开关灯
  • 原文地址:https://blog.csdn.net/Smallxu_/article/details/132918332
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号