ARM体系相关知识集锦
从源代码到cpu的执行过程?
答.c等高级语言源代码---------->.S汇编文件---------->.elf格式的二进制可执行程序---------->.bin格式的烧录文件---------->CPU取址,译码,执行(流水线)
汇编语言的本质?
答:cpu机器指令集(机器码)的助记符,是一款cpu的本质特征。不同的cpu机器指令集设计不同,因此汇编指令不能在不同的cpu之间互相移植。也因此,理论上来说用机器指令集来操作cpu是效率最高的。但是现在没人这么写代码了,所以目前来说汇编指令能最大程度发挥硬件性能,之后才轮到c语言,再之后才是上层语言比如c++,java,c#
CISC和RISC架构的特点和区别?
- CISC:设计理念:提供更多的指令集(300条左右),希望用最少的指令完成任务。
缺点:CPU工艺复杂,功耗高。 优点:编译器容易设计 intel公司至今在用
- RISC:设计理念:只提供基本功能指令集(30条左右),其他功能通过基础指令集实现。
缺点:编译器设计复杂 优点:CPU设计简单,功耗低 ARM公司在用
现在的发展方向是二者均往中间发展,RISC是为了提高性能,CISC是为了降低功耗。
IO与内存统一编址和IO与内存独立编址?
答:CPU设计的时候地址总线的位数已经确定。内存通过cpu的地址来寻址定位,然后通过cpu数据总线来读写。
CPU访问外设有两种方式:1.像访问内存一样访问外设,把寄存器当作内存地址一样来读写,叫做IO与内存统一编址
2.使用专用的CPU指令来访问某种特定外设,叫做IO与内存独立编址
什么是地址映射?
答:我们的dram本身每个字节是不具备地址的,当我们插入内存条的时候,内存条上的内存会按照预先设定的规则,进行地址映射,这样就可以访问了。
什么是冯诺依曼结构?什么是哈佛结构?
答:冯诺依曼结构:程序和代码都放在内存中,且彼此不分离的结构。 譬如intel的cpu
冯诺依曼结构因为数据和程序不区分的放在一起,所以安全和稳定性是一个问题。但是这样做处理起来简单。(程序工作在虚拟地址)
哈佛结构:分开存放程序(一般放在ROM中)和数据(一般放在RAM中)。 譬如大部分的单片机、ARM9等(除ARM7外)均采用哈佛结构
哈佛结构:程序和数据分开存放,所以安全和稳定性高,但是软件处理会相对复杂。哈佛结构决定了ARM裸机程序(使用物理地址)链接的时候比较
麻烦,必须使用复杂的链接脚本告知连接器如何组织程序。
intel和arm的对比?
答:intel:CISC架构 + IO与内存统一编址 + 冯诺依曼结构 高性能高功耗,适用于pc机
arm: RISC架构 + IO 与内存统一编址 + 哈佛结构 低功耗,稳定性高,适用于嵌入式开发
一些专业术语?
ROM RAM IROM IRAM DRAM SRAM
Norflash:可以总线式访问。上电不需要初始化。
后面的必须接口和时序访问:
NandFlash:分为SLC、MLC,前者稳定,贵。后者便宜,不稳定,必须加校验。
eMMC/iNand/moviNand oneNand(用的不多,贵,只有三星用) SD卡/TF卡/MMC卡 eSSD
SATA硬盘
s5pv210的启动过程?
答:s5pv210:内存:SRAM(上电就可运行)、DRAM(需初始化才能运行)
外存:Norflash(上电直接运行) Nandflash(需要初始化才能运行)
- SRAM从iROM中读取64KB运行,这段代码:1关看门狗+2初始化cache+3初始化栈+4初始化堆+5初始化设备复制函数+6设置时钟+7复制BL1到iROM16KB +8检查BL1校验和+9是否安全启动+10跳转到BL1
- 执行BL1(16KB)即初始化Nandflash--------->接着,加载BL2(80KB)到SRAM,即初始化DRAM
- 将从Nandflash中读取OS读取到DRAM中执行。
ARM的基本设定有哪些?
答:Byte:8bits Halfword: 16bit word: 32bit
arm有几种工作状态?
答:ARM状态、Thumb状态、Jazelle状态
arm处理器的工作模式有哪些?
答:非特权模式:user模式
特权模式:异常模式:fiq irq svc (reset /swi产生) abort undef
非异常模式:system mointor
arm一共有多少个寄存器?
答:在cortex-a之前一直都是37个寄存器,在cortex-a9出来之后变成了40个,多了一个mointer模式,所以多了3个私有寄存器。
下面显示的是37个寄存器的情况。
什么是CPU的异常处理机制?
答:当异常发生时,一定是arm状态,只有arm状态下有异常
- 异常处理流程:
1.保存cpsr到spsr中
2.设置cpsr 位---------->(1)切换当前状态位arm状态(T = 0)
----------->(2)设置相应的异常模式(M[4:0]位)
----------->(3)设置相应中断禁止位(I=1,F=1)
3.设置程序返回地址(lr_<mode> = pc)
4.设置pc为相应的异常向量
- 返回时:
1.从spsr_<mode>恢复cpsr
2.从lr_<mode>恢复pc(下一条指令)
什么是流水线?
答:cpu执行代码,会分为3个步骤,取址,译码,执行。一条指令需要分为3个周期完成,而且每个周期只能执行一次取址,因为pc指针只有一个,所以,可以将他们错开执行,这样可以最大效率的提升cpu执行代码的效率。但是引发的问题是pc指针指向的是执行代码的后两条指令。也就是说在ARM中pc = pc+8; 在thumb中pc= pc+4;
- 影响流水线效率的因素:1.分支 2.互锁
上一条指令的结果作为下一条指令的参数
分支会清空流水线
mov r1, #2 ; r1 = 2
mov r0, #1 ; r0 = 1
add r2, r1 ; r2 = r1 + r2
由于流水线的存在。所以当遇到这种第三条指令依赖前面两条指令的执行结果才能运行的情况,由于,必须等待前面两条执行完成,所以不可以直接对第三条指令取址,所以此时会清空流水线。这样小路会降低。一个较好的解决方法是吧无关代码插入到第二句和第三句话之间。
什么是指令?什么是伪指令?
答:(汇编)指令是CPU机器指令的助记符,经过编译后最终生成一串机器码,可以由CPU读取执行
(汇编)伪指令本质上不是指令(只不过和指令一起写在代码中),目的是指导编译过程,经过编译后不会生成机器码。
两种不同风格的ARM指令?
ARM官方汇编风格:指令一般大写。如 LDR R0, [R1]
GNU风格的ARM汇编:指令一般用小写字母,linux下常用。 ldr,r0,[r1]
ARM汇编特点?
CPU本身不能读取内存,需要先将内存中内容载入cpu寄存器中
ldr (load register)指令将内存内容加载到通用寄存器中
str(store register)指令将寄存器内容存入内存空间中
ldr/str组合用来实现ARM CPU和内存数据交换
ARM汇编8种寻址方式?
寄存器寻址 mov r1,r2 //r1=r2
立即寻址 mov r0,#0xff00 //r0=0xff00
寄存器移位寻址 mov r0,r1,lsl #3 //r0=r1<<3,也相当于r0=r1*8
寄存器间接寻址 ldr r1,[r2] //r1= *r2
基址变址寻址 ldr r1, [r2, #4] //r1=*(r2+4)
多寄存器寻址 ldmia r1!,{r2-r7,r12} //r1=r2,r2=r3,r3=r4,r4=r5,r5=r6,r6=r7,r7=r12
堆栈寻址 stmfd sp!,{r2-r7,lr} //上面和这个就是堆栈操作
相对寻址 beq flag //如果此时Z标志位是1那么久执行b flag
什么是指令后缀?
答:b(操作长度变为8) h(长度变为16) s(操作数变为有符号数) s(影响CPSR标志位)
常见的ARM指令?
答:数据传输指令:mov mvn 算术指令:add (add r0,r0,r1) sub rsb adc sbc rsc
逻辑指令:and orr(orr r0,r0,0xd3) eor bic(bic r0,r0,#0x1f)
比较指令:cmp(cmp r0,r1 @如果r0=r1,则Z位置1) cmn (cmn r0,r1 @判断r0r1是否互为相反数)
tst(tst r0,#0x8 @测试bit3是否为1) teq(teq r1,r2 @相等为真)
乘法指令:mvl mla umull umlal smull smlal 前导零计数:clz
cpsr访问指令?
答: mrs :读取psr内容 mrs r0,cpsr @r0=cpsr
msr:写入psr msr cpsr,r0 @cpsr=r0
跳转指令?
b :直接跳转,不返回 bl:跳转前保存返回地址,然后跳转
bx:跳转的同时切换状态(奇数则切换到Thumb状态,偶数为ARM状态)现在一般直接在arm模式下写代码所以这条指令基本不用了。
8种后缀?
ia:先传输,再地址+4 ib:先地址+4再传输 da:先传输再地址-4 db:先地址-4再传输
fd:满递增堆栈 ea:空递增堆栈
汇编中的一些符号?
@注释 #注释 :以冒号结尾的是标号 .点号代表当前地址 #立即数前面要加#或者加$
.global _start .section.text .ascii .byte .short .long .word .quad .float .string .align 4(以2的4次方对齐) .equ相当于宏定义
.end .include .arm/.code32(声明以下是arm指令) .thumb/.code16(声明以下为thumb指令)
ldr(大范围的地址加载) adr(小范围的地址加载) adrl(中等范围的地址加载指令) nop(空操作)