一.我们的的程序是如何被芯片识别的?
有时我们会想,我们使用c语言或者更高级的语言写好代码,这些类似英文字母的东西芯片是怎么识别并且按照我们的想法执行的?
上图是一个ARM芯片基本的硬件组成,我们的程序肯定是存放在FLASH上。
我们一般的项目开发中,在启动文件中或者特定场景下为了更高的效率一般使用汇编文件,其他的逻辑实现一般使用c语言进行开发,也就是像上图一样汇编文件执行完毕后,跳到c文件中开始执行。C代码通过以下过程,生成最终的二进制机器码,存入FLASH中。
(1)预处理 .i文件(展开头文件,宏定义,条件编译处理等)
(2)编译 .s汇编文件(预处理后的文件翻译成汇编代码过程)
(3)汇编 .o文件(将汇编代码翻译成对应二进制机器码的过程)
(4)链接 多个.o文件生成elf格式文件
(5)然后生成机器可识别的二进制文件。
然后将我们的二进制文件通过下载器下载到芯片的指定Flash地址上。
二.汇编代码是怎么转换为二进制机器码的?
也不难想到,就是互相约定的呗,哪几位代表什么?那么我们详细的分析下转换协议。
例:
mov r1,#0xff
1110 00 1 1101 0 0000 0001 000011111111
31~28:条件段mov 后面没有跟条件,所以为1110
27~26:保留位,恒定为00
25:标志shifter_operand段存放的是立即数还是寄存器。若为寄存器则置零,若为立即数则置一。
24~21:标明指令的类型。mov是1101
20:表明该指令是否会影响程序状态字寄存器。是则置一,否则置零
19--16位:标明第一个源操作数寄存器
15--12位:标明目的寄存器
11--0位:操作数,若为立即数则填该立即数的二进制值,若为通用寄存器则填通用寄存器标号的二进制值
那么从编写代码到转换为板子认识的语言的整过过程我们已经理解了。
三.板子内已经注入了我们的思想,那么它又是怎么转化,执行操作的?
这里需要提到一个流水线的概念。
在芯片的手册上都会提到是几级流水线那么什么是流水线??
处理器执行一条指令的三个阶段,取指,译码和执行(ARM7是冯·诺依曼结构,采用了典型的三级流水线,而ARM9则是哈佛结构,采用五级流水线技术,而ARM11则更是使用了7级流水线)。
流水线技术通过多个功能部件并行工作来缩短程序执行时间,提高处理器的效率和吞吐率简单来说,执行某条指令至少要通过取指、译码、执行三个步骤。
更形象的理解就是有一筐苹果,取出来一个,看看红不红,红就咬一口,不红就扔掉。但是这样效率比较低,假如我们在判断红不红的时候,手就开始拿下一个了,当上个咬完之后,紧接着就可以判断下一个。一点不耽误,哈哈。
我们的流水线也是这个原理。
1.第一周期,PC指向指令1,此时指令1进入流水线取指阶段
2.第二周期,PC指向指令2,此时进入译码阶段,同时取出指令2
3.第三周期,PC指向指令3,此时进入执行阶段,同时指令2进入译码阶段,指令3取指
4.第四周期,指令1执行完成,指令2和三同时推进一级,开始指令4取指。。
就想水一样,一级级推进。(有同时执行的时候)
注:
哈佛结构是一种将程序指令储存和数据储存分开的存储器结构。
冯诺依曼结构是一种将程序指令存储器和数据存储器合并在一起的结构。