arm第八天(汇编指令之跳转指令)

来源:互联网 发布:淘宝盖楼怎么玩 编辑:程序博客网 时间:2024/05/21 22:45

ARM编程模型
ARM SVC:复位,执行SWI指令
快速中断FIQ:发生高优先级的中断
中断IRQ:发生低优先级的中断
中止:访问存储器发生非法情况
未定义:执行指令,不能识别
系统:与用户模式共用寄存器的特权模式
用户:多数应用程序与系统任务运行在模式

2,工作模式的分类
异常/非异常:
异常:管理,快速中断,中断,中止,未定义
非异常:系统,用户
特权/非特权
特权:管理,快速中断,中断,中止,未定义,系统
非特权:用户模式

3,工作模式之间是是否可以切换,如何切换?
工作模式之间可以切换
切换的方式有两种:
1,处理器自动切换:当发生异常,处理器自动进入对就的异常模式
2,指令切换

工作模式之间切换需要遵循的原则:
1,特权模式之间可以随意切换
2,可以从特权模式进入到用户模式,不能直接从用户模式切换到特权模式
3,如果用户模式切换到特权模式,可以通过调用SWI指令来完成。

4,ARM的运行状态

  • ARM状态:执行ARM指令 ,一条指令32bit(4个字节)
  • 字对齐
    0x20008000
    0x20008004
    0x20008008
    0x2000800C
    0x200080010
    0x200080014

    这里写图片描述

  • Thmub状态:执行Thumb指令,一条指令16bit(2个字节)
    半字对齐
    0x20008000
    0x20008002
    0x20008004
    0x20008006
    0x20008008

5,运行状态的切换

  • 处理器自动切换
  • 用指令切换

    6,寄存器
    在cortex-A8核心里
    所有的寄存器都是没有地址,如果要用,直接使用r0,r1,r2
    寄存器都是32bit
    Ro-R12通用寄存器
    R13(SP):栈顶指针,栈顶的地址,栈是内存的一个区域
    异常模式下,都有自己的栈,对应R13保存栈顶指针
    在异常发生时,CPU会自动切换到异常模式下,先保护现场
    ,将上一模式时,再将栈中保存的值依次出栈到对应的寄存器。
    R14(LR):存放返回地址
    R15(PC):只有一个,存放取指的指令地址

    执行一条指令,分三个阶段:
    取指
    解码
    执行

ARM寄存器
ARM支持的数据类型
内存的对齐方式:字、半字、字节
ARM存储格式:大端、小端

ARM指令:

汇编代码示例:

      .text      .code 32      .global start //标号 start:      mov r0,#10  // r0 = 10      ldr r1,=3   //伪指令      add r0,r0,r1 //      b  .      .end

ARM指令

  • 分支跳转指令
    B
    B{cond}

示例

start:      cmp r0,r1  //比较r0-r1      beq  not_copy  //r0=r1相等时,跳转到not_copy执行。相当于c语言中的goto语句      mov r0,r1//r0 != r1时,r0=r1not_copy:     .....

跳转范围: PC(new) = PC(当前) + 32MB 或 PC(当前) - 32MB
这里写图片描述

24bit用来表示偏移量
1bit 符号位
23bit偏移量 2^20 = 1MB ==>8*2^20 = 8MB
arm指令地址的特点:字对齐,最后的2bit为0

bl 指令跳出去执行完以后,会跳转回来,而b指令则不会跳回来

bl 2000807 delay  //bl相当于函数的执行,执行以后,会跳回来

这里写图片描述

  • 带链接的分支指令 bl
    BL{cond}
START:   MOV R0#1    //R0=1   MOV R1#2    //R1=2   //在执行BL指令时,CPU会自动将下一条指令的地址(B.)保存到LR寄存器,再跳转   BL  DoAdd  //相当于C语言中调用函数   B.DoAdd   ADD R0,R0,R1  //RO = R0 + R1   MOV PC,LR    //返回函数指令, PC = LR ,LR是存放返回地址的
  • BX 指令,带状态切换的分支指令
    指令格式: BX{cond} Rm为寄存器
    跳转范围限制:
    绝对地址、4G范围
    如果指令指定的条件成立则:
    CPSR的T Flag = Rm[0]
    PC = Rm AND 0xfffffffe
    BX R0
  .CODE 32 //ARM_codeARM_code:  ADR R0,THUMB_code + 1 //THUMB_code + 1其实为:ADR R0,ARM_code,R0 = THUMB_code + 1  BX RO//带状态切换的跳转指令,在执行前会干以下两件事:  //1,CPSR[5] =  R0[0],把当前状态改为了Thumb状态 ;CPSR[5] = 0为表示ARM状态,CPSR[5] = 1表示THUMB状态  //2,PC = R0 & 0xFFFFFFFE  ==>把R0的第0位清0(因为前加了一个1)  ...  .CODE 16 //THUMB_codeTHUMB_code:  ADR R0,ARM_code//理由同上  BX R0//1,CPSR[5] = R0[0],将当前状态改为ARM状态       //2,PC = R0 & 0xFFFFFFFE  ....

相对跳转:与当前PC相关
B BL
绝对跳转:
BX
BX: 指令是不带返回的,绝对跳转,调整范围4G,跳转到寄存器指定的地址
1,Rm[0]给CPSR的1位,改变当前程序状态
2,PC = R0 & 0xFFFFFFFE
BLX:既带状态又带返回
1,保存一条指定地址到LR
2,Rm[0]给CPSR的1位,改变当前程序状态
3,PC = R0 & 0xFFFFFFFE
B:相对跳转,PC(跳转) = PC(当前) +/- 偏移量(32MB),跳过去不返回
BL:相对跳转,PC(跳转) = PC(当前) +/- 偏移量(32MB),跳过去会返回
CPU会将下一条指令的地址给LR,然后跳转,通过手动返回,如:

    MOV PC,LR //手动返回,一般用于函数的调用

案例:
1,编写sub.s ,sub.s代码如下:

      .text  //代码段      .code 32 //ARM模式      .global do_sub  do_sub:      mov r1,#10 //把10赋值给r1      mov r0,#0x14       sub r0,r0,r1      b . //      .end

2,安装4.4.1交叉编译器,因为这个低版本的编译器里面有arm-linux-gdb调试工具
arm-0009q3.tar.bz2
编译器安装方法

  • 首先下载解压
cd /home/tarenamkdir optcd optsudo tar jxvf /路径cd /home/tarena/opt/arm-2009q3/bin
  • 配置环境变量
cd /home/tarenavi .bashrcPATH = /解压目录/.../bin:$PATH:.   #在.bashrc中最后一行添加这一句

这里写图片描述
修改完之后执行 “source .bashrc”让环境变量生效
arm-linux-gcc -v 查看最新的版本
查看是否存在arm-linux-gdb:
arm-linux-g

安装qemu软件包,用qemu在PC机模拟板子运行环境,这样的话,就可以在PC机上查看寄存器的值。
安装方法:
1,下载安装包
2,

cd  /mnt/hgfs/1408/qemu/qemusudo dpkg -i  *              //解压安装

至此,运行环境搭建完毕

开始编译sub.s文件
cd 到sub.s文件所在目录:

cd /mnt/hgfs/1408/subarm-linux-as -g -o sub.o sub.s   #编译,-g相当于在代码中添加调试信息arm-linux-ld -e do_sub -o sub sub.o #链接,do_sub是代码中的一个全局标号,代码从这开始执行qemu-arm -g 1234 sub #将sub程序在qemu虚拟环境中运行

执行完“qemu-arm -g 1234 sub ”后,在虚拟机中重新打开一个标签页,还是在相应的目录下面,执行:

arm-linux-gdb sub(gdb)targe remote localhost:1324(gdb)s  #s相当于单独执行(gdb)s   #直到运行到 “b  .”(gdb)info r   #查看寄存器

这里写图片描述

0 0
原创粉丝点击