参考资料:朱有鹏老师物联网大讲堂核心课程

1 可编程器件从源代码到CPU执行过程

2 指令集与汇编

2.1 关于汇编

2.1.1 汇编语言与C等高级语言的差异

汇编难写,C好写
汇编无可移植性,C语言有一定可移植性,Java等更高级语言移植性更强。
汇编语言效率最高,C语言次之,Java等更高级语言效率更低。
汇编不适合完成大型复杂的项目,更高级语言更适合完成更大、更复杂的项目。

2.1.2 汇编语言的本质

汇编的实质是机器指令(机器码)的助记符,是一种低级符号语言。
机器指令集是一款CPU的编程特征,是这款CPU的设计者制定的。CPU的内部电路设计就是为了实现这些指令集的功能。机器指令集就好象CPU的API接口一样

2.1.3 总结

汇编语言就是CPU的机器指令集的助记符,是一款CPU的本质特征。
不同CPU的机器指令集设计不同,因此汇编程序不能在不同CPU间互相移植。
使用汇编编程可以充分发挥CPU的设计特点,所以汇编编程效率最高,因此在操作系统内核中效率极其重要处都需要用汇编处理。

3 RISC和CISC的区别

3.1 CISC

CISC(complex instruction set computer)复杂指令集CPU。
CISC体系的设计理念是用最少的指令来完成任务(譬如计算乘法只需要一条MUL指令即可),因此CISC的CPU本身设计复杂、工艺复杂,但好处是编译器好设计。CISC出现较早,至今Intel还一直采用CISC设计。
一般典型CISC CPU指令在300条左右。

3.2 RISC

RISC(Reduced Instruction-Set Computer)精简指令集CPU
RISC的设计理念是让软件来完成具体的任务,CPU本身仅提供基本功能指令集。因此RISC CPU的指令集中只有很少的指令,这种设计相对于CISC,CPU的设计和工艺简单了,但是编译器的设计变难了。
RISC CPU常用指令30条左右。

3.3 CPU设计方式发展

早期简单CPU,指令和功能都很有限。
CISC年代 —— CPU功能扩展依赖于指令集的扩展,实质是CPU内部组合逻辑电路的扩展。
RISC年代 —— CPU仅提供基础功能指令(譬如内存与寄存器通信指令,基本运算与判断指令等),功能扩展由使用CPU的人利用基础架构来灵活实现。

3.4 发展趋势

没有纯粹的RISC或CISC,发展方向是RISC与CISC结合,形成一种介于2者之间的CPU类型。

4 统一编址 独立编址 哈佛结构 冯诺依曼结构

4.1 内存和IO概念及其访问方式

4.1.1 内存

内存是程序的运行场所,内存和CPU之间通过总线连接,CPU通过一定的地址来访问具体内存单元。

访问方式

内存通过CPU的地址总线来寻址定位,然后通过CPU数据总线来读写。
CPU的地址总线的位数是CPU设计时确定的,因此一款CPU所能寻址的范围是一定的,而内存是需要占用CPU的寻址空间的。
内存与CPU的这种总线式连接方式是一种直接连接,优点是效率高访问快,缺点是资源有限,扩展性差。

4.1.2 IO

IO(input and output)是输入输出接口,是CPU和其他外部设备(如串口、LCD、触摸屏、LED等)之间通信的道路。一般的,IO就是指CPU的各种内部或外部外设。

访问方式

这里IO指的是与CPU连接的各种外设。
CPU访问各种外设有2种方式:一种是类似于访问内存的方式,即把外设的寄存器当作一个内存地址来读写,从而以访问内存相同的方式来操作外设,叫IO与内存统一编址方式;另一种是使用专用的CPU指令来访问某种特定外设,叫IO与内存独立编址。

4.2 独立编址与统一编址对比

由于内存访问频率高,因此采用总线式连接,直接地址访问,效率最高。

4.2.1 独立编址

IO与内存独立编址方式,优势是 不占用CPU地址空间,缺点是CPU设计变复杂了。

4.2.2 统一编址

IO与内存统一编址方式,优势是IO当作内存来访问,编程简单;缺点是IO也需要占用一定的CPU地址空间,而CPU的地址空间是有限资源。

4.3 冯诺依曼结构与哈佛结构

4.3.1 程序和数据

程序运行时两大核心元素:程序 + 数据.
程序是我们写好的源代码经过编译、汇编之后得到的机器码,这些机器码可以拿给CPU去解码执行,CPU不会也不应该去修改程序,所以程序是只读的。
数据是程序运行过程中定义和产生的变量的值,是可以读写的,程序运行实际就是为了改变数据的值。

4.3.2 冯诺依曼结构

程序和数据都放在内存中,且不彼此分离的结构称为冯诺依曼结构。譬如Intel的CPU均采用冯诺依曼结构。

4.3.3 哈佛结构

程序和数据分开独立放在不同的内存块中,彼此完全分离的结构称为哈佛结构。譬如大部分的单片机(MCS51、ARM9等)均采用哈佛结构。

4.3.4 两种结构对比

冯诺依曼结构中程序和数据不区分的放在一起,因此安全和稳定性是个问题,好处是处理起来简单。
哈佛结构中程序(一般放在ROM、flash中)和数据(一般放在RAM中)独立分开存放,因此好处是安全和稳定性高,缺点是软件处理复杂一些(需要统一规划链接地址等)。

5 软件编程控制硬件的关键-寄存器

5.1 什么是寄存器

寄存器属于CPU外设的硬件组成部分。
CPU可以像访问内存一样访问寄存器。
寄存器是CPU的硬件设计者制定的,目的是留作外设被编程控制的“活动开关”。
正如汇编指令集是CPU的编程接口API一样,寄存器是外设硬件的软件编程接口API。使用软件编程控制某一硬件,其实就是编程读写该硬件的寄存器。
寄存器中每个bit位都有特定含义,因此编程操作时需要位操作。
单个寄存器的位宽一般和CPU的位宽一样,以实现最佳访问效率。

5.2 两类寄存器

SoC中有2类寄存器:通用寄存器和特殊功能寄存器。
通用寄存器(ARM中有37个)是CPU的组成部分,CPU的很多活动都需要通用寄存器的支持和参与。
SFR(special function register,特殊功能寄存器)不在CPU中,而存在于CPU的外设中,我们通过访问外设的SFR来编程操控这个外设,这就是硬件编程控制的方法。

6 小结

6.1 ARM是RISC架构

常用ARM汇编指令只有二三十条。
ARM是低功耗CPU。
ARM的架构非常适合单片机、嵌入式,尤其是物联网领域;而服务器等高性能领域目前主导还是Intel。

6.2 ARM是统一编址的

大部分ARM(M3 M4 M7 M0 ARM9 ARM11 A8 A9等)都是32位架构。
32位ARM CPU支持的内存少于4G,通过CPU地址总线来访问。
SoC中的各种内部外设通过各自的SFR编程访问,这些SFR的访问方式类似于访问普通内存,这叫IO与内存统一编址。

6.3 ARM是哈佛结构的

常见ARM(除ARM7外)都是哈佛结构的.
哈佛结构保证了ARM CPU运行的稳定性和安全性,因此ARM适用于嵌入式领域。
哈佛结构也决定了ARM裸机程序(使用实地址即物理地址)的链接比较麻烦,必须使用复杂的链接脚本告知链接器如何组织程序;对于OS之上的应用(工作在虚拟地址之中)则不需考虑这么多。

7 ARM的编程模式

大部分ARM提供:ARM 指令集(32-bit) 、Thumb 指令集(16-bit )、Thumb2指令集(16 & 32bit)。这种特点使得ARM既能执行16位指令,又能执行32位指令。cpu可以在ARM态和Thumb之间切换。

8 ARM的七种工作模式

此部分参考资料:仲一的《嵌入式软件开发笔试面试指南》

(1) 用户模式(USR)

用户模式是用户程序的工作模式,它运行在操作系统的用户态,它没有权限去操作其它硬件资源。只能执行处理自己的数据,也不能切换到其它模式下,要想访问硬件资源或切换到其它模式只能通过软中断或产生异常。

(2) 系统模式(SYS)

系统模式是特权模式,不受用户模式的限制。用户模式和系统模式共用一套寄存器,操作系统在该模式下可以方便的访问用户模式的寄存器,而且操作系统的一些特权任务可以使用这个模式访问一些受控的资源。

说明:用户模式与系统模式两者使用相同的寄存器,都没有SPSRSaved Program Statement Register,已保存程序状态寄存器),但系统模式比用户模式有更高的权限,可以访问所有系统资源。

(3) 一般中断模式(IRQ)

一般中断模式也叫普通中新模式,用干处理一般的中新请求,通常在硬件产生中新信号之后自动进入该模式,该模式为特权模式,可以自由访问系统硬件资源。

(4) 快速中断模式(FIQ)

快速中断模式是相对一般中断模式而言的,它是用来处理对时间要求比较紧急的中断请求,主要用于高速数据传输及通道处理中。(快中断有许多(R8~R14)自己的专用寄存器,发生中断时,使用自己的寄存器就避免了保存和恢复某些寄存器。如果异常中断处理程序中使用它自己的物理寄存器之外的其他寄存器,异常中断处理程序必须保存和恢复这些寄存器)

(5) 管理模式(SVC)

管理模式是CPU上电后默认模式,因此,在该模式下主要用来做系统的初始化,软中断处理也在该模式下。当用户模式下的用户程序请求使用硬件资源时,通过软件中断进入该模式。

说明:系统复位或开机、软中断时进入到SVC模式下。

(6) 终止模式(ABT):

中止模式用于支持虚拟内存或存储器保护,当用户程序访问非法地址,没有权限读取的内存地址时,会进入该模式,linux下编程时经常出现的segment fault(段错误)通常都是在该模式下抛出返回的。

(7) 未定义模式(UND):

未定义模式用于支持硬件协处理器的软件仿真,CPU在指令的译码阶段不能识别该指令操作时,会进入未定义模式。

小结

1.除了用户模式外,其它6种模式称为特权模式。所谓特权模式,即具有如下权利:
MRS(把状态寄存器的内容放到通用寄存器);MSR(把通用寄存器的内容放到状态寄存器中)。
由于状态寄存器中的内容不能够改变,因此,要先把内容复制到通用寄存器中,然后修改通用寄存器中的内容,再把通用寄存器中的内容复制给状态寄存器中,即可完成“修改状态寄存器”的任务。
2.剩下的六种模式中除去系统模式外,统称为异常模式。
3.各种模式的切换,可以是程序员通过代码主动切换(通过写CPSR寄存器);也可以是CPU在某些情况下自动切换。
4.七种模式作用?
CPU是硬件,OS是软件,软件的设计要依赖硬件的特性,硬件的设计要考虑软件需要,便于实现软件特性。操作系统有安全级别要求,因此CPU设计多种模式是为了方便操作系统的多种角色安全等级需要。

9 ARM的37个通用型寄存器

9.1 七种模式下各自的寄存器组合

1、特殊功能寄存器是通过地址访问,通用(区别SFR)寄存器是通过名称访问。
2、37=15(r0-r12 r15 cpsr) + 12(六组r13 r14) + 5(异常模式spsr) + 5(快速中断的r8-r12)
3、ARM共有37个32位长度寄存器,其中30个为“通用型”(相对于pc等作用固定的寄存器),1个固定用作PC,一个固定用作CPSR,5个固定用作5种异常模式下的SPSR。
4、ARM总共有37个寄存器,但是每种模式下最多只能看到18个寄存器,其他寄存器虽然名字相同但是在当前模式不可见。
5、USR和SYS共用一套寄存器
6、r13(sp):堆栈指针,每种模式下都有独自的堆栈指针,可以保证出问题时各个模式不会发生连带影响。
7、r14(lr):用来存储返回地址,例如从USR切换到IRQ模式时,会将USR模式的返回地址存在IRQ的lr中,将来 bl lr 返回USR模式。
8、r15(pc):程序计数器,总是指向当前正在取指的指令地址,因此:正在执行的指令地址=pc-8。
9、cpsr:程序状态寄存器,用来记录cpu的运行状态。
10、spsr:用来保存上个模式下的cpsr。

9.2 cpsr

CPSR中各个bit位表明了CPU的某些状态信息,这些信息非常重要,和后面学到的汇编指令息息相关(譬如BLE指令中的E就和CPSR中的Z标志位有关)CPSR中的I、F位和开中断、关中断有关,CPSR中的mode位(bit4~bit0共5位)决定了CPU的工作模式,在uboot代码中会使用汇编进行设置。

10 ARM异常处理方式

10.1 异常概念

正常工作之外的流程都叫异常。
异常会打断正在执行的工作,并且一般我们希望异常处理完成后继续回来执行原来的工作,中断是异常的一种。
FIQ、IRQ、Supervisor属于中断,中断属于cpu正常工作范畴,而终止模式和未定义模式是cpu不知所措,是真正的异常。

10.2 异常向量表


所有的CPU都有异常向量表,这是CPU设计时就设定好的,是硬件决定的。当异常发生时,CPU会自动动作(PC跳转到异常向量处处理异常,有时伴有一些辅助动作)异常向量表是硬件向软件提供的处理异常的支持,程序员要做的,是告诉cpu怎样处理相应异常。

10.3 ARM异常处理机制

当异常产生时, ARM core:拷贝 CPSR 到 SPSR_<mode>设置适当的 CPSR 位: 改变处理器状态进入 ARM 态改变处理器模式进入相应的异常模式设置中断禁止位禁止相应中断 (如果需要)保存返回地址到 LR_<mode>设置 PC 为相应的异常向量
返回时, 异常处理需要:从 SPSR_<mode>(恢复thumb态)从LR_<mode>恢复PC
Note:这些操作只能在 ARM 态执行.

10.4 总结

异常处理中有一些是硬件自动做的,有一些是程序员需要自己做的。需要搞清楚哪些是需要自己做的,才知道如何写代码。以上说的是CPU设计时提供的异常向量表,一般称为一级向量表。有些CPU为了支持多个中断,还会提供二级中断向量表,处理思路类似于这里说的一级中断向量表。

11 ARM汇编指令集

11.1 指令与伪指令

(汇编)指令是CPU机器指令的助记符,经过编译后会得到一串10组成的机器码,可以由CPU读取执行。
(汇编)伪指令本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供的,目的是用来指导编译过程,经过编译后伪指令最终不会生成机器码。

11.2两种不同风格的ARM指令

ARM官方的ARM汇编:指令一般用大写、Windows中IDE开发环境(如ADS、MDK等)常用。如: LDR R0, [R1]
GNU风格的ARM汇编:指令一般用小写字母、linux中常用。如:ldr r0, [r1],我们使用gnu工具链,相应用gun风格下的汇编。

11.3 常用伪指令

常用gnu伪指令

(1)global _start @ 给_start外部链接属性
(2).section .text @ 指定当前段为代码段
(3).ascii .byte .short .long .word
(4).quad .float .string @ 定义数据
(5).align 4 (2的四次方) @ 以16字节对齐
(6).balignl 16 0xabcdefgh @ 16字节对齐填充
(7).equ @ 类似于C中宏定义

最重要的几个伪指令

(1)ldr 大范围的地址加载指令
(2)adr 小范围的地址加载指令
(3)adrl 中等范围的地址加载指令
(4)nop 空操作
ARM中有一个ldr指令,还有一个ldr伪指令,一般都使用ldr伪指令而不用ldr指令,ldr伪指令无需考虑立即数是否合法。

gnu汇编中的一些符号

(1)@ 用来做注释。可以在行首也可以在代码后面同一行直接跟,和C语言中//类似
(2)# 做注释,一般放在行首,表示这一行都是注释而不是代码。
(3):以冒号结尾的是标号 标号绑定指令地址
(4) . 点号在gnu汇编中表示当前指令的地址
(5)# 立即数前面要加#或$,表示这是个立即数

11.4 常用指令

常用ARM指令1:数据处理指令

(1)数据传输指令 mov mvn
(2)算术指令 add sub rsb adc sbc rsc
(3)逻辑指令 and orr eor bic
(4)比较指令 cmp cmn tst teq
(5)乘法指令 mvl mla umull umlal smull smlal
(6)前导零计数 clz

常用ARM指令2:cpsr访问指令

mrs & msr
mrs用来读cpsr,msr用来写cpsr
CPSR寄存器比较特殊,需要专门的指令访问,这就是mrs和msr。

常用ARM指令3:跳转(分支)指令

(1)b 直接跳转(就没打开算返回)
(2)bl branch and link,跳转前把返回地址放入lr中,以便返回,以便用于函数调用
(3)bx跳转同时切换到ARM模式,一般用于异常处理的跳转

常用ARM指令4:访存指令

(1)单个字/半字/字节访问 ldr/str
(2)多字批量访问 ldm/stm
(3)SWP
SWP R1,R1,[R0] ; 将R1 的内容与R0 指向的存储单元的内容进行交换
SWP R1,R2,[R0] ; 将R0 指向的存储单元内容读取一字节数据到R1 中(高24 位清零); 并将R2 的内容写入到该内存单元中(最低字节有效)
使用SWP 指令可以方便地进行信号量的操作:

    12C_SEM EQU 0x40003000…12C_SEM_WAITMOV R0,#0LDR R0,=12C_SEMSWP R1,R1,[R0]            @取出信号量,并设置其为0CMP R1,#0                  @判断是否有信号BEQ 12C_SEM_WAIT       @若没有信号,则等待换

常用ARM指令5:软中断指令

swi(software interrupt)
软中断指令用来实现操作系统中系统调用

11.5 一些概念

什么是协处理器

SoC内部另一处理核心,协助主CPU实现某些功能,被主CPU调用执行一定任务。
ARM设计上支持多达16个协处理器,但是一般SoC只实现其中的CP15.(cp:coprocessor)
协处理器和MMU、cache、TLB等处理有关,功能上和操作系统的虚拟地址映射、cache管理等有关。

八种后缀

(1)ia(increase after)先传输,再地址+4
(2)ib(increase before)先地址+4,再传输
(3)da(decrease after)先传输,再地址-4
(4)db(decrease before)先地址-4,再传输
(5)fd(full decrease)满递减堆栈
(6)ed(empty decrease)空递减堆栈
(7)fa(·······) 满递增堆栈
(8)ea(·······)空递增堆栈

四种栈

空栈:栈指针指向空位,每次存入时可以直接存入然后栈指针移动一格;而取出时需要先移动一格才能取出
满栈:栈指针指向栈中最后一格数据,每次存入时需要先移动栈指针一格再存入;取出时可以直接取出,然后再移动栈指针
增栈:栈指针移动时向地址增加的方向移动的栈
减栈:栈指针移动时向地址减小的方向移动的栈

!的作用

ldmia r0, {r2 - r3}
ldmia r0!, {r2 - r3}
感叹号的作用就是r0的值在ldm过程中发生的增加或者减少最后写回到r0去,也就是说ldm时会改变r0的值。

^的作用

ldmfd sp!, {r0 - r6, pc}
ldmfd sp!, {r0 - r6, pc}^
^的作用:在目标寄存器中有pc时,会同时将spsr写入到cpsr,一般用于从异常模式返回

立即数

合法立即数与非法立即数
ARM指令都是32位,除了指令标记和操作标记外,本身只能附带很少位数的立即数。因此立即数有合法和非法之分。
合法立即数:经过任意位数的移位后非零部分可以用8位表示的即为合法立即数

ARM裸机——2.ARM体系结构(1)相关推荐

  1. BSP板机支持包、linux启动分析、ARM裸机编程

    文章目录 一.BSP 二.驱动 驱动的基本要素 三.启动分析 1.uboot 2.uboot的作用 3.uboot相关命令 关键的内容: 1)bootargs,启动参数 2)启动命令 3)修改启动延时 ...

  2. ARM裸机开发篇3:ARM汇编语言程序设计

    写在前面: 本文章为<ARM Cortex-A7裸机开发篇>系列中的一篇,全系列总计11篇.笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板). 针对FS-MP ...

  3. 开发板、原理图和数据手册-1.3.ARM裸机第三部分-朱有鹏-专题视频课程

    开发板.原理图和数据手册-1.3.ARM裸机第三部分-7453人已学习 课程介绍         本期课程承上启下,主要目的是让大家把开发板玩起来.很多同学买了开发板接上线,串口都连不上,或者连刷系统 ...

  4. 定时器、看门狗和RTC-1.9.ARM裸机第九部分-朱有鹏-专题视频课程

    定时器.看门狗和RTC-1.9.ARM裸机第九部分-6771人已学习 课程介绍         本期课程主要讲述SoC中的时间相关的外设,包括定时器.看门狗定时器和实时时钟RTC.首先讲述了定时器的基 ...

  5. 【笔记】ARM裸机程序开发_part1

    ARM裸机开发的一些基础知识,基于x210开发板 课没有认真听完,也没接触过裸机的项目可供上传,但是了解一下总是好的=v= 授课老师:朱有鹏 听课辣鸡:宕机酱 ==================== ...

  6. ARM裸机篇(五)——异常和中断

    linux系列目录: linux基础篇(一)--GCC和Makefile编译过程 linux基础篇(二)--静态和动态链接 ARM裸机篇(一)--i.MX6ULL介绍 ARM裸机篇(二)--i.MX6 ...

  7. ARM裸机开发篇2:ARM微处理器指令系统

    目录 ARM微处理器指令系统 ARM处理器寻址方式 数据处理指令寻址方式 内存访问指令寻址方式 ARM处理器指令集 数据操作指令 乘法指令 Load/Store指令 跳转指令 状态操作指令 协处理器指 ...

  8. 朱老师ARM裸机学习笔记(一):计算机基础知识

    RISC和CISC的区别 CISC(complex instruction-set computer)复杂指令集 特点: 指令较多,较丰富,CISC的CPU 较难设计,Intel是典型的CISC体系C ...

  9. ARM裸机篇---启动代码分析

    ARM裸机篇---启动代码分析 先搞清楚启动代码和Bootloader的区别,启动代码是指CPU复位后到进入C语言的main函数之前需要执行的那段汇编代码. 下面的代码先暂且这样吧,没啥注释的,时间关 ...

最新文章

  1. BS开发中常用的Javascript技术
  2. 【错误记录】创建密钥报错 ( Key was created with errors: Warning: JKS 密钥库使用专用格式。建议使用 “ keyto “ 迁移到行业标准格式 PKCS12 )
  3. 防火墙(2)——firewalld
  4. 线性电源与开关电源的区别
  5. Python之数据分析(figure图形对象、Numpy连线特殊点、图像多元布局)
  6. 谷歌眼镜设计规范之度量和网格
  7. 数学中 对数log 指数
  8. 谷歌 Chrome 浏览器怎样开启黑暗模式?
  9. ajax 的四步法处理
  10. [C++] 麻将胡牌算法
  11. OpenStack虚拟机rebuild和evacuate差异梳理
  12. Material UI 带复选框表格获取选中值(索引)
  13. Scapy:快速syn洪水攻击(syn flood)
  14. 有没有简单易懂不枯燥的Java入门教程?
  15. 北大前沿交叉学院数据科学计算机,北京大学数据科学(统计学)考研经验-北大前沿交叉学科研究院考研...
  16. 滴滴开源 Levin:数据闪电加载方案
  17. 两个路由器桥接共享一个宽带
  18. 2019 CCF CSP-J第一轮
  19. 最大股票收益问题(数组最大差问题)
  20. Greetings!(枚举子集+dp)

热门文章

  1. 端口转发工具ngr0k
  2. 关闭页面出现确定,取消按钮
  3. 洛谷P3400 仓鼠窝(单调栈)
  4. 架构 Varnish+Nginx+PHP(FastCGI)+MYSQL5+MemCache
  5. 使用极狐GitLab CI/CD部署应用到Kubernetes集群的方案
  6. 腾讯放大招,首张区块链发票亮相深圳,日后发票报销几分钟搞定
  7. iPhone,iPhone4,iPad程序的启动画面
  8. MySQL_MySQL基础查询(DQL)
  9. mac下 android nkd环境搭建
  10. Android中控件setVisibility(View.Gone)失效(经测试是非UI线程导致)