arm知识基本

来源:互联网 发布:mac搜狗怎么打罗马数字 编辑:程序博客网 时间:2024/05/16 20:31
GCC 编译流程: 预取->编译->汇编->连接
        预取: 主要是一些宏定义的替换。
        编译: 主要是编译成汇编的代码。
        汇编: 主要是把汇编代码编译成二进制。
        连接:主要是将二进制的连接相关的函数变成二进制可执行的程序。


一 ARM 基础知识,arm架构一般是哈佛结构哈佛结构一般指令和数据是分开存放的,程序和数据在不同的存储空间中。

arm芯片对于浮点数运算:
            Linux默认是硬浮点运算的,硬浮点运算一般有对应的FPU(浮点运算器),而在一般的代码中有软浮点库中进行浮点运算(软浮点的运算效率比较低)

1.ARM 指令集
(1)ARM 指令集  (32bit)
(2)Thumb 指令集(16bit)

2.ARM 工作模式

U(usr)  S(sys)  A(abt)   U(udf)  F(fiq)  I(irq)  S(svc)  M(mon)

非特权模式: 不可以自己切换模式,也不可以访问一些特殊的协处理寄存器
usr 

特权模式  : 可以自己切换模式,也可以系统中特殊的寄存器资源 
除usr模式外,剩下的都是

异常模式  : 程序在运行的时候,出现了突发情况,ARM核自动进入的模式

A(abt)  U(udf)  F(fiq)  I(irq)  S(svc)

arm 指令流水线:
        3级流水线:
            

        无论处理器处于何种状态,程序计数器R15(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指令。

人们一般会习惯性的将正在执行的指令作为参考点,即当前第1条指令。

所以,PC总是指向第3条指令,

或者说PC总是指向当前正在执行的指令地址再加2条指令的地址。

pc 总是指向:正在取址的这条指令。

3.ARM 寄存器资源

R0-R15  CPSR  SPSR

(1)R13 (sp) : 栈指针寄存器,用来栈的位置
(2)R14 (lr) : 连接寄存器,用来记录在代码跳转之前pc的值(目的:便于代码的返回 [lr -> pc]),记录返回时值。
(3)R15 (pc) : 程序计数器,用来记录CPU将要执行的指令所在的地址,
(4)CPSR     : CPU的状态寄存器
(5)SPSR     : 在异常发生的时候,用来记录异常之前CPSR的值

31 30  29  28                 7    6     5  4         0                            
--------------------------------------------------------
N | Z | C |V     ......... | I  |  F  | T   |  mode 
 -------------------------------------------------------

(1)N (negative)   : 它置1的时候,表示计算的结果为负数
(2)Z (zero)       : 它置1的时候,表示计算的结果为0 
(3)C (carry)      : 如果两个数做加法,产生了进位,则置1或两个数相减没有产生借位则置1, 否则置0
(4)V (overflower) : 符号位溢出,例如:两个正数相加结果为负数

   char a = 127;
   char b = 100;
   char c = a + b;

   if(a > b){

   }

(7)I(irq)          : 它置1的时候,表示禁用慢中断 ,0表示使能 
(6)F(fiq)          : 它置1的时候,表示禁用快中断 , 0表示使能 
(7)T(Thumb)        : 它置1的时候,表示ARM核在Thumb状态 ,0表示在ARM状态 
(8)mode            : 表示当前ARM核所在的模式             


总结:
(1)每种都共享的寄存器 
    r0-r7 , cpsr , pc 
(2)除了FIQ模式,其他模式共享 
    r8-r12 
(3)每种异常模式私有的寄存器
    r13 , r14 , spsr 

(4)每种模式最多可以拥有的寄存器
   r0-r15 , cpsr ,spsr  


4.ARM异常处理

(1)ARM 核自动做的事情
   [1]cpsr 保存到异常模式的 spsr 
   [2]修改cpsr
         [1]进入ARM状态
         [2]切换到异常模式
         [3]禁用中断

   [3]将pc的值保存到异常模式的LR寄存器
   [4]将pc的值设到异常向量表的相应位置

(2)程序员需要做的事情
   A.产生异常之前的准备工作
     [1]编写异常向量表(就是一块内存,这一块内存中存放的是跳转到异常处理函数的指令)
     [2]实现异常处理函数
     [3]告诉ARM核异常向量表基地址

    问题:异常向量表可以存放在哪里?
    回答:在Cortex-A系列之前的核,异常向量表可以存放在0x0000,0000 或 0xffff,0000,默认ARM核在0x0000,0000 
         地址寻找,我们可以通过CP15协处理器的C1寄存器来设置
         在Cortex-A系列之后,异常向量表可以存放在任何位置,取决于CP15的C12寄存器(只需要将异常向量表
         基地址写到cp15的c12寄存器)

   B.异常处理函数编写
     exception_handler:
        [1]将公用寄存器的值压栈保护
        [2]异常处理 
        [3]异常返回
            [1]恢复公用寄存器的值(出栈)
            [2]恢复cpsr (异常模式的spsr->cpsr)
            [3]恢复pc   (异常模式的lr  ->pc)