• 2023/9/27 -- ARM


    【汇编语言相关语法】

    1.汇编语言的组成部分

    1. 1.伪操作:不参与程序的执行,但是用于告诉编译器程序该怎么编译
    2. .text
    3. .global .end .if .else .endif .data
    4. 2.汇编指令
    5. 编译器将一条汇编指令编译成一条机器码,在内存里一条指令占4字节内存,一条指令可以实现一个特定的功能
    6. 3.伪指令
    7. 不是指令,看起来像是一条指令,可以实现和指令类似的功能。一条伪指令实际上可能是由多条指令共同实现
    8. 4.注释
    9. 单行注释: @
    10. 多行注释 /* */
    11. 条件编译
    12. .if 0
    13. 指令段
    14. .else
    15. 指令段
    16. .endif

    2.汇编指令的介绍

    1. 1.基本数据操作指令
    2. 数据搬移指令 =
    3. 数据移位指令 << >>
    4. 数据算数运算指令 + - * /
    5. 位运算指令 & | ~ ^
    6. 数据比较指令
    7. 2.跳转指令
    8. 3.内存读写指令
    9. 4.状态寄存器读写指令
    10. 5.软中断指令

    3.汇编指令的基本语法格式

    1. 指令的基本格式:
    2. <opcode>{<cond>}{s} <Rd>, <Rn>, <shifter_operand>
    3. 解释:
    4. <opcode>:指令码
    5. {<cond>}:条件码
    6. {s}:状态位,如果在指令后面加上s,则运算的结果会影响CPSR的条件位
    7. <Rd>:目标寄存器
    8. <Rn>:第一操作寄存器 只能是寄存器
    9. <shifter_operand>:第二操作数,可以是寄存器,也可以是立即数
    10. 按照指令码将第一操作寄存器和第二操作数进行运算,将运算后的结果保存在目标寄存器
    11. 注意:
    12. 1.一条汇编指令一般占一行
    13. 2.汇编不区分大写小写

    【汇编指令】

    1.数据搬移指令

    1.1 格式

    1. <opcode>{<cond>}{s} <Rd>, <shifter_operand>
    2. 解释:
    3. <opcode>:指令码
    4. {<cond>}:条件码
    5. {s}:状态位,如果在指令后面加上s,则运算的结果会影响CPSR的条件位
    6. <Rd>:目标寄存器
    7. <shifter_operand>:第一操作数,可以是寄存器,也可以是立即数
    8. 按照指令码将第一操作数运算后的结果保存在目标寄存器
    9. 指令码功能:
    10. mov:将第一操作数的值保存在目标寄存器
    11. mvn:将第一操作数的值按位取反,将结果保存在目标寄存器

    1.2 示例

    1.3 立即数的概念

    定义:能够直接当作指令的一部分参与到指令的执行过程中的数据就是立即数.立即数由一个0-255范围内的数循环右移偶数位获得。

    在指令的32为中将低12位预留保存立即数的数据

    1. 如何判断一个数据是不是立即数:
    2. 0-255范围内找一个数,让它循环右移偶数位(一个0-15范围内的数*2得到),如果能够得到这个数据,则这个数就是一个立即数。
    3. 循环右移:最低位移出去的数补到最高位
    4. 0000 0000 0000 0000 0000 0000 0000 1010
    5. 右移两位: 0000 0000 0000 0000 0000 0000 0000 0010
    6. 循环右移两位: 100000 0000 0000 0000 0000 0000 0000 10
    7. ex:
    8. 0X1040000 0000 0000 0000 0000 0001 0000 0100
    9. 循环右移2位-》000000 0000 0000 0000 000000 0100 0001 -》0x41
    10. 换句话说,将0x41循环右移30位得到0X104,所以,0X104是一个立即数
    11. 0X101:0000 0000 0000 0000 0000 0001 0000 0001
    12. 0X101找不到一个0-255范围内的数循环右移得到它,所以0X101不是立即数

    1.4 将非立即数保存至寄存器中

    1. 伪指令:
    2. LDR 目标寄存器,=数值
    3. 将指定的数据放在目标寄存器中
    4. ex:LDR r1,=0X12345678

    2.移位指令

    2.1 格式以及指令码

    1. 格式:<opcode>{<cond>}{s} <Rd>, <Rn>, <shifter_operand>
    2. 解释:将第一操作寄存器的数值移位第二操作数指定的位数,将结果保存在目标寄存器中
    3. 指令码:
    4. LSL:左移运算 低位补0
    5. LSR:右移运算 高位补0
    6. ROR:循环右移:低位移出的值补到高位

    2.2 示例

    1. 1.左移
    2. mov r0,#0XFF
    3. lsl r1,r0,#0X4 @将R0的值左移4位保存在r1寄存器 R1结果:0XFF0
    4. 2.右移
    5. mov r0,#0XFF
    6. lsr r1,r0,#0X4 @将R0的值右移4位保存在r1寄存器 R1结果:0XF
    7. 3.循环右移
    8. mov r0,#0XFF
    9. ror r1,r0,#0X4 @将R0的值循环右移4位保存在r1寄存器 R1结果:0XF000000F
    10. 4.c风格写法
    11. mov r0,#0XFF
    12. ror r1,r0,#(0X1<<2) @将R0的值循环右移4位保存在r1寄存器 R1结果:0XF000000F

    3.位运算指令

    3.1 格式以及功能码

    1. 格式:<opcode>{<cond>}{s} <Rd>, <Rn>, <shifter_operand>
    2. 解释:将第一操作寄存器和第二操作数进行位运算,将结果保存在目标寄存器中
    3. 指令码:
    4. and:与 与001不变
    5. orr:或 或110不变
    6. eor:异或 相同为0 不同为1
    7. bic:按位清零指令,想将哪一位设置为0,只需要用bic指令给这一位运算一个1即可

    3.2 示例

    1. 1.and:
    2. mov r0,#0XFF
    3. and r1,r0,#0XF0 @R1结果为0XF0
    4. 2.ORR:
    5. mov r0,#0XFF
    6. orr r1,r0,#0XF000 @R1结果为0XF0FF
    7. 3.EOR:
    8. ldr r0,=0xf0f0
    9. EOr r1,r0,#0XFF @R1结果为0XF00F
    10. 0000 0000 0000 0000 0000 0000 1111 1111
    11. 0000 0000 0000 0000 1111 0000 1111 0000
    12. 结果:0000 0000 0000 0000 1111 0000 0000 1111 -》0XF00F
    13. 4.BIC
    14. ldr r0,=0xFF
    15. BIC r0,r0,#(0x1<<5) @将R0的值第5位清0 @R0结果为0XDF

    3.3 练习

    1. LDR r1,=0X12345678 @将0X12345678存放在r1寄存器
    2. 0001 0010 0011 0100 0101 0110 0111 1000
    3. 1.将R1寄存器的第4位清0,其他位不变
    4. and r1,r1,#(~(0X1<<4))
    5. 或者BIC R1,R1,#(0x1<<4)
    6. 2.将r1寄存器第7位置1,其他位不变
    7. orr r1,r1,#(0X1<<7)
    8. 3.将r1寄存器[3128]清0,其他位不变
    9. and r1,r1,#(~(0Xf<<28))
    10. 或者BIC R1,R1,#(0xF<<28)
    11. 4.将r1寄存器[7:4]置1,其他位不变
    12. orr r1,r1,#(0XF<<4)
    13. 5.将r1寄存器[15:11]设置为10101,其他位不变
    14. @先清0
    15. BIC R1,R1,#(0X1F<<11)
    16. @再置位
    17. orr r1,r1,#(0X15<<11)

    4.算数运算指令

    4.1 格式以及指令码

    1. 格式:<opcode>{<cond>}{s} <Rd>, <Rn>, <shifter_operand>
    2. 解释:将第一操作寄存器的值和第二操作数进行算数运算,结果保存在目标寄存器中
    3. add:加法运算
    4. adc:进行加法运算时需要考虑CPSR的条件位
    5. sub:减法运算
    6. sbc:进行减法运算时需要考虑CPSR的条件位
    7. mul:乘法运算

    4.2 示例

    1. 1.ADD:加法
    2. ex1: mov r1,#1
    3. mov r2,#2
    4. add r3,r1,r2@r3=r1+r2
    5. ex:
    6. mov r1,#0XFFFFFFFE
    7. mov r2,#2
    8. addS r3,r1,r2@r3=r1+r2 @运算的结果影响到条件位
    9. 2.SUB
    10. mov r1,#0XFFFFFFFE
    11. mov r2,#2
    12. sub r3,r1,r2@r3=r1-r2
    13. ex2:
    14. mov r1,#0XFFFFFFFE
    15. mov r2,#2
    16. subs r3,r2,r1@r3=r2-r1
    17. 3.ADC
    18. mov r1,#0XFFFFFFFE
    19. mov r2,#2
    20. ADDS r3,r2,r1 @r3=r1+r2
    21. ADC R4,R2,#3 @R4=R2+3+cpsr(C位) 6
    22. 4.sbc:减法运算考虑条件位
    23. mov r1,#0XFFFFFFFE
    24. mov r2,#2
    25. SUBS r3,r2,r1 @r3=R2-R1 4
    26. sbC R4,R1,#3 @R4=R1-3-CPSR(C位取反)

    4.3 64位数据进行算数运算

    1. 原则:
    2. 一个 64位数保存在两个寄存器
    3. 32位运算,低32位运算
    4. mov r1,#0XFFFFFFFE @保存第一个数据的低32
    5. mov r2,#2@保存第一个数据的高32
    6. mov r3,#3 @保存第二个数据的低32
    7. mov r4,#4 @保存第2数据的高32
    8. @低32位运算要求影响条件位
    9. ADDS R5,R1,R3@R5保存运算后结果的低32
    10. ADC R6,R2,R4@R6寄存器保存运算结果的高32位,需要考虑条件位

    5.比较指令

    1. 格式:
    2. cmp 第一操作数,第二操作寄存器
    3. 比较两个数据
    4. cmp命令本质:实际上就是比较的两个数进行减法运算,并且减法运算的结果会影响到CPSR寄存器的条件位
    5. 通常比较指令完毕之后会使用条件码进行判断,根据判断的结果做不同的逻辑

    条件码

    在一个指令后面加上条件码的助记词后缀,如果满足条件码对应的条件,我们就会进行对应的指令操作,否则不进行操作

    1. mov r1,#3
    2. mov r2,#4
    3. cmp r1,r2 @比较两个数
    4. SUBHI r3,r1,r2 @如果r1>r2 进行减法运算
    5. MULEQ r3,r1,r2@如果两数相等,进行乘法运算
    6. ADDCC R3,R1,R2@如果r1<r2 ,进行加法运算

    6. 跳转指令

    1. 格式:
    2. <opcode>{<cond>} 标签
    3. 功能:跳转到指定的标签下
    4. 指令码:
    5. b:跳转时不影响LR寄存器的值
    6. ex:.text
    7. .global _start
    8. _start:
    9. mov r1,#3
    10. mov r2,#4
    11. b fun1 @程序跳转
    12. mul r5,r1,r2
    13. stop:
    14. b stop
    15. fun1:
    16. add r4,r1,r2
    17. .end
    18. bl:跳转时影响LR寄存器的值
    19. .text
    20. .global _start
    21. _start:
    22. mov r1,#3
    23. mov r2,#4
    24. bl fun1 @程序跳转
    25. mul r5,r1,r2
    26. stop:
    27. b stop
    28. fun1:
    29. add r4,r1,r2
    30. mov pc,lr @程序返回
    31. .end

    【任务】

    实现1-100的累加

    1. .text
    2. .globl _start
    3. _start:
    4. MOV R0,#0
    5. MOV R1,#1
    6. MOV R2,#100
    7. FUN:
    8. CMP R1,R2
    9. ADDNE R0,R0,R1
    10. ADDNE R1,R1,#1
    11. BNE FUN
    12. stop:
    13. b stop
    14. .end

  • 相关阅读:
    Windows10安装配置MySQL超详细教程(2022年)
    贪心算法概念
    聚苯乙烯微球/碳纳米管复合修饰杂化聚醚砜纳滤膜/聚苯乙烯氧化铁磁性微球
    解决 vue 项目开发越久 node_modules包越大的问题
    Redis初启(一)
    实例:用C#.NET手把手教你做微信公众号开发(21)--使用微信支付线上收款:H5方式
    Angular 怎么封装基础组件?
    Powershell - 环境设置
    华为OD机考算法题:靠谱的车
    设计模式(二)-创建者模式(2)-工厂模式
  • 原文地址:https://blog.csdn.net/weixin_54147737/article/details/133362201