arm汇编指令集

  1. 4arm指令集概述

    1. .c文件里面包含
      1. 语句a++;
      2. 注释//
      3. 预编译指令(条件编译)#if 1. .... #else .... #endif
    2. 汇编:
      1. 汇编中的符号
        1. 指令:能够编译生成一条32bit机器码,并且能被cpu识别和执行
          1. 数据处理指令:进行数学运算、逻辑运算、
          2. 跳转指令:实现程序的跳转,本质就是修改了PC寄存器
          3. Load/Store指令:访问(读写)内存
          4. 状态寄存器传送指令:用于访问(读写)CPSR寄存器
          5. 软中断指令:给CPU发送中断信号,触发软中断
          6. 协处理器指令:操作协助处理器的指令
        2. 伪指令:本身不是指令,编译器可以将其替换成若干条指令
        3. 伪操作:不会生成指令,只是在编译阶段告诉编译器怎么编译
    3. 数据处理指令:
      1. 数据处理指令:数学运算、逻辑运算
        1. @数据搬移指令R1=1
          1. MOV R1, #1 
          2. MOV R2, #2
          3. MOV R3, #3
          4. MOV PC, #0 @0存的是第一条指令R1,这样就相当于一个小的循环,pc最后两位没有值,但是如果强制写成值,最后两位要改成00,因为他要保持四的整数倍
          5. MOV R2, R1
        2. MVN  R0, #0xFF.  @R0 = ~0xFF 相当于按位取反后再搬移指令
        3. 立即数@编译不通过就不是立即数,编译通过就是立即数
        4. 立即数的本质就是包含在指令当中的数,属于指令的一部分
          1. MOV R0,  #0x12 @是立即数
          2. MOV R0, #0x12345678 @不是立即数,超长了
        5. 立即数和普通变量区别是变量独占空间,立即数是指令一部分
        6. 立即数优势是:取指的时候就可以将其读取到CPU,不用单独去内存读取,速度快
        7. 缺点是:不能是任意的32位的数字,有局限性
        8. MOV R0, #0xFFFFFFF @不是立即数,但是编译器不报错,类似伪指令,CPU编译成认识的
        9. @ 加法指令
          1. MOV R2, #5
          2. MOV R3, #3
          3. ADD R1,R2,R3 @R1 = R2+R3
          4. ADD R1, R2 ,#5
          5. ADD R1, #5, #5 //这种是错的 ADD R1, #5, R1 //这种也是错的
        10. @减法指令
          1. SUB R1, R2, R3
          2. SUB R1, R2, #3
          3. sub缺点:只能寄存器-寄存器,寄存器-数,所以设计逆向减法指令
        11. 逆向减法指令
          1. RSB R1,R2,#3 @R1 = 3-R2,还是最后写数
        12. 乘法指令MUL,不能用立即数
          1. MUL R1, R2,R3 @R1=R2*R3
          2. 乘法指令只能是两个寄存器相乘
          3. arm不能直接算除法,通过替换成右移指令
        13. 按位与指令
          1. AND R1,R2,R3 @R1=R2&R3
        14. 按位或指令
          1. ORR R1,R2,R3 @R1=R2|R3
        15. 按位异或指令
          1. EOR R1,R2,R3 @R1=R2^R3
        16. 左移指令
          1. MOVR2, #0xF0
          2. MOV $3, #0x2
          3. LSL R1,R2,R3 @R1=(R2<<R3)
        17. 右移指令
          1. LSR R1,R2,R3 @R1=(R2>>R3)
        18. 位清零指令
          1. MOV R2, #0xFF
          2. BIC R1,R2,#0xF @把R2最后4位清0保存给R1,R2不会变,只是把结果给R1(第二操作数中的哪一位为1,就将第一操作寄存器的中哪一位清零,然后将结果放入目标寄存器)
        19. 数据运算指令的格式:
          1. 《操作码》《目标寄存器》 《第一操作寄存器》《第二操作数》
            1. 操作码:表示执行哪种操作
            2. 目标寄存器: 用于存储运算的结果
            3. 第一操作寄存器:存储第一个参与运算的数据(只能是寄存器)
            4. 第二操作数:第二个参与运算的数据(可以是寄存器,也可以是立即数)
          2. 数据运算指令的格式扩展
            1. MOV R1, R2, LSL #1@R1=(R2<<1)
    4. CPSR寄存器
      1. 数据运算指令对条件位(N、Z、C、V)的影响
      2. MOV R1, #3
      3. SUBS R2, R1, #5
      4. 默认情况下数据运算不会对条件位产生影响,当在指令后加后缀"S"后可以影响
      5. 两个64位的数据做加法运算,把高低位拆开分别放在cpu运算,
        1. 第一个数的低32位放在R1,
        2. 第一个数的高32位放在R2
        3. 第二个数的低32位放在R3
        4. 第四个数的高32位放在R4
        5. 运算结果低的32位放在R5
        6. 运算结果高的32位放在R6
        7. MOV R1, #0x00000001
        8. MOV R2, #0x00000001
        9. MOV R3, #0x00000002
        10. MOV R4, #0x00000002
        11. ADD R5, R1,R3.  @无法解决进位问题
        12. ADD R6, R2,R4。 @无法解决进位问题
        13. 解决方案:
          1. ADDS R5,R1,R3
          2. ADC R6,R2,R4 @ADC带进位的加法 R6=R2+R4+‘C’位
      6. 带借位的减法指令SBC
        1. 第一个数0x00000002 00000001
        2. 第二个数0x00000001 00000005
        3. MOV R1,#0x00000001
        4. MOV R2,#0x00000002
        5. MOV R3,#0x00000005
        6. MOV R4,#0x00000001
        7. SUBS R5, R1, R3
        8. SBC R6, R2,R4@本质是R6=R2-R4-'!C' (C的取反)
    5. 跳转指令:实现程序的跳转,本质就是修改了PC寄存器
      1. 方式一:直接去修改PC寄存器的值
      2. 方式二:B FUNC:本质也是修改PC,编辑器修改PC的值, LR的值自动改成下一条指令的地址(B不带返回的跳转指令,本质就是将PC寄存器的值改成跳转标号下第一条指令的地址)
      3. 方式三:BL FUNC带返回的跳转指令,本质就是将PC寄存器的值修改成跳转标号下的第一条指令的地址,同时将跳转指令下一条指令的地址存储到LR寄存器
        1. 在FUNC方法里面最后需要:MOV PC,LR
        2. c里面BX指令跳转,貌似还切换指令集,了解用
    6. ARM指令的条件码

      1. CMP R1,R2
      2. CMP本质就是一条减法指令(SUBS),只是没有将运算的结果存入寄存器
      3. BEQ ==    NEQ not equal !=
      4. cpu本身就是个电路
      5. ARM指令集中大多数指令都可以带条件码后缀
    7. 内存访问指令
      1. Load/Store指令:访问(读写)内存
      2. 写内存

        1. STR R1,[R2] @将R1寄存器中的数据存储到R2指向的内存空间
        2. 调试结果如下:说明是小端对齐,低地址对应低有效位,高地址对应高有效位
      3. 读内存

        1. LDR R3,[R2] @将内存中R2指向的内存空间中的数据读取到R3寄存器
        2. STRB(byte 一个字节只把最低的八位写进去)
        3. STRH(half word 半个字,两个字节,只把最低的16位写进去)
        4. c语言不通类型的变量对应不同的指令
        5. 寻址方式就是CPU去寻找一个操作数的方式
    8. ARM指令的寻址方式

      1. 立即寻址
        1. MOV R1,#1  //参与运算的数来自于立即数
        2. ADD R1, R2, #1
      2. 寄存器寻址
        1. ADD R1,R2,R3
      3. 寄存器移位寻址
        1. MOV R1,R2,LSL #1
      4. 寄存器间接寻址
        1. STR R1,[R2] // 用寄存器指向内存
      5. 基址+变址寻址

      6. 基址+变址寻址的索引方式
    9. 多寄存器内存访问指令
    10. 多寄存器内存指令的寻址方式
      1. STMIA(increase after)
      2. STMIB(increase before)
      3. STMDA(decrease after)
      4. STMDB(decrese before)
    11. 栈的种类和应用
      1. 栈的概念:
        1. 栈的本质就是一段内存,程序运行时用于保存一些临时数据,如局部变量、函数的参数、返回值以及程序跳转时需要保护的寄存器
      2. 栈的种类:压栈,出栈

        1. STMFD(不是新命令,编译器自动编译成STMDB)
        2. LDMFD(不是新命令,编译器自动编译成STMIA出栈)
      3. 栈的应用举例

        1. 叶子函数的调用过程
        2. 应用栈后:
    12. CPSR寄存器

      1. Current Program Status Register,当前程序状态寄存器

      2. CPSR寄存器分为四个域,【31:24】为条件域用F表示,【23:16】为状态域用S表示,【15:8】为预留域用X表示,【8:0】为控制域用C表示

      3. Bit[4:0]

        1. [10000]User

        2. [10001]FIQ

        3. [10010]IRQ

        4. [10011]SVC

        5. [10111]Abort

        6. [11011]Undef

        7. [11111]System

        8. [10110]Moniter

      4. Bit[5]

        1. [0]ARM状态

        2. [1]Thumb状态

      5. Bit[6]

        1. [0]开启FIQ 硬件中断

        2. [1]禁止FIQ

      6. Bit[7]

        1. [0]开启IRQ 硬件中断

        2. [1]禁止IRQ

      7. 读CPSR

        1. MRS R1, CPSR @ 把cpsr的值读到r1,上电默认svc模式

      8. 写CPSR

        1. MSR CPSR, #0x10 @user模式

        2. MSR CPSR, #0xD3 @svc模式,在user模式下,不能修改CPSR,非特权模式

    13. 软中断指令

      1. swi指令在linux内核应用较多

    14. 协处理器指令

      1. 操控制协处理器的指令

        1. 协处理器数据运算指令

          1. CDP

        2. 协处理器存储访问指令

          1. STC将协处理器中的数据存储到存储器中 

          2. LDC将存储器中的数据读取到协处理器中

        3. 协处理器寄存器传送指令

          1. MRC将协处理器中寄存器的数据传送到ARM处理器中的寄存器

          2. MCR将ARM处理器寄存器中的数据传送到协处理器中的寄存器

    15. 伪指令

      1. 本身不是指令,编译器可以将其替换成若干条指令

      2. NOP.空指令

        1.     MOV R0, R0 这个指令不做任何事情,但是浪费cpu时间

  2. 伪操作和混合编程

    1.   伪操作:不会生成代码,只是在编译阶段告诉编译器怎么编译

    2. .GNU伪操作一般都以"."开头

    3. .global symbol

    4. 将symbol声明成全局

    5. .local symbol

    6. 将symbol声明成局部

    7. .equ DATA, oxFF // .equ相当于c语言里面的宏

    8. MOV R1, #DATA

    9. .maroc         .endm 封装代码段

    10. #if1 #endif    .rept .endr

      .weak symbol 弱化符号。 B func  

      .word 在当前地址申请一个字的空间并将其初始化

      .byte在当前地址申请一个字节的空间并将其初始化 

      .align 2 告诉编译器这一行之后的代码对其,2是2的几次方,align后用2的2次方对其:即4字节对齐

      .arm 告诉编译器后面指令都是arm指令

      .thumb告诉编译器后面指令都是thumb指令

    11. .space 在当前地址申请任意个字节的空间并将其初始化

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值