ARM学习笔记4

本文深入解析ARM汇编指令集的特点与应用,包括数据处理、寄存器操作、访存及栈处理等指令,并介绍伪指令的作用及合法立即数的概念。
ARM常用汇编指令集

指令: 由CPU提供,最终生成机器码,由CPU执行.
伪指令: 由编译器提供,指导编译过程,编译后不产生机器码.

ARM汇编5个特点
  1. ldr/str架构

    RISC架构的CPU不能直接操作内存,cisc可以直接操作内存.

    LDR/STR架构:CPU和内存数据交换必须通过寄存器来读写.

    ldr(load register):内存数据->通用寄存器

    str(store register):通用寄存器数据->内存

  2. 八大寻址方式

    1. 寄存器和数据直接交换: 立即数寻址 #
      mov r0,#0xffe  // 把数据0xffe 存到r0,相当于C语言的r0=0xffe;

    2. 寄存器之间交换数据:寄存器寻址 rx
      mov r0,r1   //r1 数据存到r0,相当于C语言的r0=r1;

    3. 寄存器和寄存器里的数据移位后进行交换:寄存器移位寻址 lsl, lsr
      mov r0,r1,lsl #3  // mov r0,(r1 <<3) r1里的数据LSL 3位后存到r0,相当于C语言的r0=r1<<3;

    4. 寄存器和内存之间交换数据: 寄存器间接寻址 []
      ldr r0,[r2]  //r2寄存器中地址所指的数据加载到r0中,[r2]表示内存,r2里存放内地地址
            //r2相当于C语言的指针,r0=(r2); 解引用.

    5. 寄存器和内存地址偏移后交换数据:基址变址寻址[rx,#x]
      ldr r0,[r2,#3]  //r2寄存器中地址偏移3后所指向的数据加载r0
             //r2是基地址,#3是偏移量,相当于C语言r0=(r2+3);解引用.

    6. 多个寄存器同时和内存交换数据:多寄存器寻址 rx!,{rx-rx,rx}
      ldmia r1!,{r2-r7,r12}  //r1所指向的内存地址开始的数据连续加载到r2至r7 和r12 寄存器中,r1类似数组首地址,数组有8个元素,分别把这8个元素加载到后面8个寄存器中.
                 //”!”作用,运算过程中增量值保存在r1中,没有则保存r1原始值(是否改变r1原始值)

    7. 栈和寄存器之间交换数据:堆栈寻址sp!,{rx-rx,rx}
      stmfd sp!,{r2-r7,r12}   //栈指针sp所指地址中数据连续加载到r2至r7 和r12 寄存器中, sp栈基地址

      ldmfd sp!,{r2-r6,pc}^   //”^”作用,目标寄存器有PC时,会同时把spsr值写到CPSR中 ,从异常模式中返回到正常模式(中断返回,快速返回)

    8. pc地址和pc偏移量之间交换数据:相对寻址 flag:
      beq flag     //跳转到flag标号地方,本质是通过PC和PC本身作为参考,加一个偏移量,PC当前执行的地址向前或向后偏移.
      flag:

  3. 指令后缀

    同一个指令附加不同后缀后衍生出很多不同的指令,常用如下:

    • B(Byte)功能不变,操作长度变为8      //ldr ldrb
    • H(Half)功能不变,操作长度变为16     //ldr ldrh
    • S(Signed)功能不变,操作数变为有符号   //ldr ldrsh
    • S(cpSr)影响CPSR标志位(NZCV)     //mov movs r0,#0;执行后影响标志位
  4. 条件执行后缀

    • 条件后缀是否成立不是取决本句代码,是本句之前代码执行后的结果是否影响标志位
    • 条件后缀只影响本句代码是否执行,不影响前后一句代码是否执行

    常用如下:(*号使用频率高)

    条件码标志含义
    *EQZ=1相等
    *NEZ=0不相等
    CS/HSC=1无符号大于或等于
    CC/LOC=0无符号小于
    MLN=1负数
    PLN=0正数或零
    *VSV=1溢出
    VCV=0没有溢出
    *HIC=1,Z=0无符号大于
    LSC=0,Z=1无符号小于或等于
    GEN=V有符号大于或等于
    LTN!=V有符号小于
    *GTZ=0,N=V有符号大于
    LEZ=1,N!=V有符号小于或等于
    ALX无条件执行(指令默认条件)
    NVX从不执行

5 . 多级流水线

为了增加处理器指令流的速度.
                     ARM        Thumb
        执行          pc-8        PC-4
            解码          pc-4        PC-2
                取址          pc          PC

汇编指令详解

1. 数据处理指令:
1 .1 .数据传输指令
 mov    //mov r1,r0                 寄存器和寄存器之间传输
        //mov r1,#0xff              寄存器和数据之间传输
 mvn    //mvn r0,r1                 按位取反后再存放
1.2. 算术指令
      add
      sub   //sub r2, r1,r0             r2(目标)=r1-r0(源)
      rsb
      adc
      sbc
      rsc
1.3. 逻辑指令
      and   //                          逻辑与
      orr   //                          逻辑或
      eor   //                          逻辑异或
      bic   //bic r0,r1,#0x1f           特定位清零,将r1中的数的bit0到bit4(0x1f=000.....11111)清零后赋值给r0
1.4. 比较指令(重在过程中影响标志位,不加后缀自动影响CPSR)
      cmp   //  cmp r0,r1               等价于sub r2,r0,r1(r2=r0-r1)比较两个寄存器的数是否相等,
      cmn   //  cmn r0,r1               等价于add r2,r0,r1(r2=r0+r1)两数相加是否为0(两数互补)
      tst   //  tst r0,#0xf             测试某些位是否为0(0xf=1111)bit0-bit3,对特定数进行位与r0 and 0xf
      teq   //  teq r0,r1               对2个数进行异或r0 eor r1
1.5. 乘法指令
      mvl
      mla
      umull
      umlal
      smull
      smlal
1 .6. 前导零计数
       clz  //                          获取一个数前面几个零如0xf=00000000.....1111    
2. cpsr spsr操作指令
cpsr:  1个,程序状态寄存器
spsr:  5个状态各1个,作用是当从普通模式进入异常模式时,保存之前普通模式下的cpsr,保证再返回普通模式时可以恢复原来的cpsr

      mrs   // mrs r0,cpsr              把CPSR的值读到r0中
      msr   // msr cpsr ,r0             把加工后的数据(r0)重新写到CPSR中
            // cpsr_f                   只是模式位
            // cpsr_c                   只是控制位
3. 跳转指令
      b     //  b flag                          (绝对跳转)直接跳转,不保存返回地址,不打算返回
      bl    //  bl flag                         (函数调用)跳转前保存返回地址到lr(r14)中,再跳转
      bx    //                                   thumb下跳转,跳转同时切换到ARM态
4. 访存指令
    ldr/str     //                      单字、半字、字节访问,每周期只能访问4个字节内存.
    ldm/stm     //                      多字批量访问 单周期多寄存器读写,多字节批量操作,提高访问效率
    swp         //  swp r1,r2,[r0]      内存和寄存器互换,把r0内存地址的数据放到r1中同时把r2的数据写回r0内存地址中
                //  swp r1,r1,[r0]      一条指令完成内存和寄存器互换
4 .1. 栈与ldm/stm的处理
        stmx sp, {rx-rn}            //x为后缀,rx-rn为通用寄存器
        stmia sp,{r0-r12}           //sp栈内存地址 r0-r12寄存器,存放方式按照ia后缀规则,后缀如下:                      
8种后缀:(*号使用频率高,ARM默认满减栈)
*ia:(increase after)先传输数据再地址+4i:加a:先
ib:(increase before)先地址+4再传输数据
da:(decrease after)先传输数据再地址-4d:减b:后
db:(decrease before)先地址-4再传输数据

———————————————————————————————————————————————

*fd:(fulldecrease)满栈递减sp所指地址有数据先向低地址移动合适位置再存储数据f:满d:递减
ed:(emptydecrease)空栈递减sp所指没有数据先存储数据再向低地址移动合适位置
fa:满栈递增sp所指地址有数据先向高地址移动合适位置再存储数据e:空a:递增
ea:空栈递增sp所指没有数据先存储数据再向高地址移动合适位置

———————————————————————————————————————————————
四种栈:

空栈:sp指向空位存数据:直接存放取数据:先移动后取
满栈:sp指向满栈存数据:先移动后存放取数据:直接取数据
增栈:地址向高位栈指针移动方向为地址增加方向
减栈:地址向低位栈指针移动方向为地址减小方向

———————————————————————————————————————————————

5 . 软中断指令
 swi(software interrupt)                    //软中断指令用来实现操作系统中系统调用
6 . 协处理器(coprocessor)
soc中另一个处理核心协助主处理器实现某些功能,被主处理器调用执行一定任务。
ARM架构支持多达16(0-15)个协处理器,一般SOC中只实现其中的第15个也就是CP15.协处理MMU\Cache\TLB等处理有关,功能上和操作系统的虚拟地址映射\cache管理等有关.

mrc             //读协处理器
mcr             //写协处理器

mcr{<cond>} p15, <opcode_1>, <Rd>, <Crn>, <Crm>, {<opcode_2>}   //mrc p15 ,0, r0, c1, c0, 0  把CP15的C1寄存器值读到arm的R0寄存器中       
opcode_1:   对于CP15永远为0
Rd:         ARM的通用寄存器名字(不能为R15/PC)
Crn:        CP15的寄存器,合法值c0~c15
Crm:        CP15的寄存器,一般均为c0
opcode_2:   一般省略或为0
7 . 伪指令
伪指令由编译器提供,目的为了指导编译过程,编译后不产生机器码.
/*  */      //注释
//          //注释    
@           //注释
:           //标号
.           //当前指令的地址           b . 相当于C语言while(1)
#           //代表立即数
立即数:
ARM 32位指令,除了指令标记和操作标记外,本身只能附带很少位数的立即数,所以有合法和非法立即数
合法立即数:无限移位后非零位可用8位表示        //0x000000ff,0x000ff000,
非法立即数:无限移位后非零位无法用8位表示       //0x000f0f00,0x001ff000,
7 . 1. 常用伪指令:
    .global _star                       //给_star 声明为外部链接属性(目的为了别的文件可以访问、引用)
    .section .text                      //指定当前段位代码段(链接脚本中运用)
    .ascii .byte .short.long .word      //ascii字符、 byte字节、 short 2字节、 long 4字节、 word 4字节(相当于定义变量)
    .quad.float.string                  //定义数据 quad 8字节、 float 浮点、 string 字符串
    .align 4                            //以16字节对齐 2^4=16 按照16字节(不填充)
    .balignl 16 0xfff                   //16字节对齐加填充,b:位填充、align:要对齐、l:long以4字节为单位填充、16:16字节对齐、 0xfff:用fff填充中间的地址(填充原料) 
    .equ                                //类似C中的宏定义  #define

    .end                                //文件结束
    .include                            //文件包含
    .arm/.code32                        //arm 代码
    .thumb/.code16                      //thumb 代码

    ldr             //大范围的地址加载  
                    //ldr  r0,#0xff :指令 ,ldr r0,=0xffff :伪指令    (指令后面加#,需要考虑合法和非法立即数。伪指令后面加=,不需要考虑合法和非法立即数.)加载地址由链接脚本决定.
    adr             //小范围的地址加载 
                    //adr以PC为基准表示地址(相对地址).加载地址由运行时决定.
    adrl            //中等范围的地址加载
    nop             //空操作
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值