叨叨游戏网
您的当前位置:首页杜春雷《ARM体系结构与编程》学习笔记

杜春雷《ARM体系结构与编程》学习笔记

来源:叨叨游戏网
第一章 ARM概述及其基本编程模型
第二章 ARM指令分类及其寻址方式
  1. ARM指令格式如下:<opcode>{<cond>}{S} <Rd>,<Rn>,<shifter_operand>,指令长度为32位,其中opcode为指令助记符;cond为执行条件(在ARMv5之前所有的指令都是有条件执行的);S指明是否影响CPSR寄存器的值;Rd为目标寄存器;Rn为第1个操作数的寄存器;shifter_operand为第2个操作数。
  2. 数据处理指令的第二个操作数shifter_operand可以采用立即数、寄存器或者寄存器移位(算术右移ASR、逻辑左移LSL、逻辑右移LSR、循环右移ROR、扩展的循环右移RRX,移位的位数可以用立即数或者寄存器表示),在立即数寻址中立即数是由一个8位的常数循环右移偶数位得到的,所以有些立即数可能不合法(P24)。
  3. 字及无符号字节的Load/Store指令的寻址方式:Load指令将内存中的数据读取到寄存器中,Store指令则相反(用32位指令编码中的L位控制)。ARM的Load/Store指令有两种,一类是操作32位的字类型数据以及8位无符号字节型数据,另一类是操作16位半字类型的数据以及8位的有符号字节类型数据。各类型的Load/Store指令的寻址方式由两部分组成,一部分为一个基址寄存器Rn,另一部分为一个地址偏移量,基址寄存器可为任意通用寄存器,地址偏移量可为立即数、寄存器、寄存器及一个移位常数。寻址方式的地址计算方式有3种:偏移量方法(如指令LDR R0,[R1,-#4];将内存单元R1-4中的字读取到R0中)、事先更新方法(如指令LDR R0,[R1,#4]!;将内存单元(R1+4)中的数据读取到寄存器R0中,同时R1=R1+4)、事后更新方法(如指令LDR R0,[R1],R2;将地址R1的内存单元数据读取到R0中,然后R1=R1+R2)。
  4. 杂类Load/Store指令的寻址方式:包括操作数为半字、操作数为带符号的字节数据和操作数为双字的Load/Store指令。
  5. 批量可以实现在一组寄存器和一块连续的内存单元之间传输数据。指令中编号低的寄存器对应于内存单元中的低地址单元,编号高的寄存器对应于内存单元中的高地址单元。地址变化方式共有四种:IA(事后递增方式)、IB(事先递增方式)、DA(事后递减方式)、DB(事先递减方式)(P52)。
  6. 协处理器Load/Store指令的寻址方式:此类指令可实现在ARM处理器和协处理器之间批量传输数据。寻址方式有4种:偏移量、事先更新、事后更新、非索引(P59)。
第三章 ARM指令集介绍
  1. ARM指令可分为6类:跳转指令、数据处理指令、程序状态寄存器(PSR)传输指令、Load/Store指令、协处理器指令和异常中断产生指令。
  2. 跳转指令:通过直接向PC中写入目标地址值可以实现4GB的地址空间中任意跳转。在ARMv5及以上的体系中,实现了ARM指令集和Thumb指令集的混合使用,传送到PC寄存器中的目标地址值的bits[0]为0时目标程序为ARM指令,为1时目标程序为Thumb指令。ARM的跳转指令可以从当前指令向前或向后32MB的地址空间跳转,这类指令有以下4种:B(跳转指令,范围为-32M~+32M,指令和目标地址处的指令都是ARM指令)、BL(带返回的跳转指令,跳转时会将PC寄存器中大的值保存到LR寄存器中,范围为-32M~+32M,指令和目标地址处的指令都是ARM指令)、BLX(带返回和状态切换的跳转指令,在跳转目标的地址存储在寄存器中时目标地址处的指令可以是ARM指令或者Thumb指令,而若跳转目标地址由立即数给出则目标地址处的指令只能是Thumb指令)、BX(带状态切换的跳转指令,目标地址处的指令可以是ARM指令或者Thumb指令)。
  3. 数据处理指令分为:1数据传送指令;2算术逻辑运算指令;3比较指令。常见的指令有:MOV、MVN(可将数据的反码传送到目标寄存器)、ADD、ADC(带进位加法指令)、SUB、SUC(带借位减法指令)、RSB(逆向减法指令)、RSC(带位逆向减法指令)、AND、ORR(逻辑或)、EOR(逻辑异或)、BIC(位清除指令,将立即数的反码与Rn寄存器的值做逻辑与,结果存放在Rd中,与1做BIC操作可将相应位清除为0)、CMP(相当于SUBS指令,但CMP不保存运算结果而只改变标志寄存器)、CMN(相当于ADDS指令,但CMN不保存运算结果而只改变标志寄存器)、TST(相当于ANDS指令,但TST不保存运算结果而只改变标志寄存器)、TEQ(相当于EORS,但TEQ不保存运算结果而只改变标志寄存器,TEQ可用来判断两个数是否相等或者符号是否相同)。
  4. 乘法指令:MUL(32位乘法指令,结果为32位,可以为有符号或者无符号乘法,所有操作数均在寄存器中)、MLA(32位乘加指令,结果为32位,可以为有符号或者无符号乘加,所有操作数均在寄存器中)、SMULL(将两个有符号32位数相乘,结果为位分别存放在两个32寄存器中,所有操作数均在寄存器中)、SMLAL(将两个有符号32位数的位乘积结果与某有符号位数相加,结果为位分别存放在两个32寄存器中,所有操作数均在寄存器中)、UMULL(将两个无符号32位数相乘,结果为位分别存放在两个32寄存器中,所有操作数均在寄存器中)、UMALL(将两个无符号32位数的位乘积结果与某有符号位数相加,结果为位分别存放在两个32寄存器中,所有操作数均在寄存器中)。
  5. CLZ指令(自ARMv5开始引入):用于计算寄存器操作数最高端0的个数,如果操作数大的bit[31]为1则返回0,若操作数为0则返回32。
  6. 状态寄存器访问指令:MRS指令可将状态寄存器的内容传送到通用寄存器,MSR指令可将通用寄存器的内容传送到状态寄存器。程序不能通过直接修改CPSR中的T控制位直接将程序状态切换到Thumb状态,必须通过BX等指令完成程序状态的转换。,通常修改状态寄存器是通过“读取-修改-写回”的操作序列来实现的(P85)。
  7. Load/Store指令(ARM中只有Load/Store指令可以访问存储器,其他指令则操作寄存器中的数据):此类指令有两种,一种是操作32位的字类型数据以及8位无符号的字节类型数据。另一类操作16位的半字类型数据以及8位的有符号字节类型数据。常见指令有:LDR(字数据读取指令,一般地址按字对齐)、LDRB(字节数据读取指令,从内存中将一个8位的字节数据读取到指令中的目标寄存器中,并将寄存器大的高24位清0)、LDRBT(用户模式的字节数据读取指令,当在级的处理器模式下使用本指令时,内存系统将该操作当作一般用户模式下的内存访问操作)、LDRH(半字数据读取指令,从内存中将一个16位的半字数据读取到指令中的目标寄存器中,并将寄存器大的高24位清0)、LDRSB(有符号的字节数据读取指令,从内存中将一个8位的字节数据读取到指令中的目标寄存器中,并将高24位进行符号扩展)、LDRSH(有符号的半字数据读取指令,从内存中将一个16位的半字数据读取到指令中的目标寄存器中,并将高16位进行符号扩展)、LDRT(用户模式的字数据读取指令,当在级的处理器模式下使用本指令时,内存系统将该操作当作一般用户模式下的内存访问操作)、STR(字数据写入指令,一般地址按字对齐)、STRB(字节数据写入指令,将寄存器中的低8位写入到内存中)、STRH(半字数据写入指令,将寄存器中的低16位写入到内存中)、STRT(用户模式的字数据写入指令,当在级的处理器模式下使用本指令时,内存系统将该操作当作一般用户模式下的内存访问操作)、STRBT(用户模式的字节数据写入指令,当在级的处理器模式下使用本指令时,内存系统将该操作当作一般用户模式下的内存访问操作)(P97)。
  8. 批量Load/Store内存访问指令:可以一次对连续的内存单元读取或写入数据,编号低的寄存器对应内存中的低地址单元,编号高的寄存器对应内存中的高地址单元。常见指令有:LDM(共有3类,分别为批量内存字数据读取指令、用户模式的批量内存字数据读取指令,^符号可表明是用户模式、带状态寄存器的批量内存字数据读取指令)、STM(共有2类,分别为:批量内存字数据写入指令、用户模式的批量内存字数据写入指令,^符号可表明是用户模式)(P100)。
  9. 信号量操作指令:信号量用于进程之间的同步和互斥,对信号量的操作是原子操作,即在一条指令中完成信号量的读取和修改操作。信号量相关指令有:SWAP(交换指令,将寄存器Rn中对应的内存字单元的数据读取到寄存器Rd中,并将Rm寄存器中的值写入到该内存字单元)、SWPB(字节交换指令,将寄存器Rn中对应的内存字单元的数据读取到寄存器Rd的低8位,剩余高24位置0,并将Rm寄存器中的低8位写入到该内存字节单元)(P104)。
  10. 异常中断产生指令:SWI(软中断指令,ARM正式利用这种机制实现在用户模式中对操作系统模式的程序的调用,24位立即数指明请求的中断服务类型)、BKPT(断点中断指令,产生软件断点,供程序调试使用)(P106)。
  11. ARM协处理器指令:ARM支持16个协处理器,在程序执行过程中,每个协处理器忽略属于ARM处理器和其他协处理器的指令,当一个协处理器硬件不能执行属于它的协处理器指令时,将产生未定义指令异常中断。常见指令有:CDP(协处理器数据操作指令)、LDC(协处理器数据读取指令)、STC(协处理器数据写入指令)、MCR(ARM寄存器到协处理器寄存器的数据传送指令)、MRC(协处理器寄存器到ARM寄存器的数据传送指令)(P110)。
  12. 一些基本的ARM指令功能段见P110。Thumb指令集并没有改变ARM体系的程序设计模型,Thumb指令集中的数据处理指令的操作数仍然是32位的,指令寻址地址也是32位的(P121)。
第四章 ARM汇编语言程序设计
  1. ARM汇编语言中,程序由指令、伪操作、宏指令组成。伪操作有:符号定义伪操作、数据定义伪操作、汇编控制伪操作、数据帧描述伪操作(主要用于调试)、信息报告伪操作、其他伪操作。
  2. 符号定义伪操作:GBLA伪操作声明一个全局的算术变量,并将其初始化为0、GBLL伪操作声明一个全局的逻辑变量,并将其初始化为{FALSE}、GBLS伪操作声明一个全局的串变量,并将其初始化为空””(上述三个伪操作的作用范围为包含该变量的源程序,如果这些伪操作重新声明已经声明过的变量,则以后一次声明为准,P123)、LCLA伪操作声明一个局部的算术变量,并将其初始化为0、LCLL伪操作声明一个局部的逻辑变量,并将其初始化为{FALSE}、LCLS伪操作声明一个局部的串变量,并将其初始化为空””(上述三个伪操作的作用范围为包含该变量的宏代码的一个实例,如果这些伪操作重新声明已经声明过的变量,则以后一次声明为准,P123)、SETA伪操作给一个算术变量赋值、SETL伪操作给一个逻辑变量赋值、SETS伪操作给一个串变量赋值、RLIST伪操作用于为一个通用寄存器列表定义名称,定义的名称可以在LDM/STM指令中使用,寄存器列表的访问次序总是先访问较低的寄存器再访问编号较高的寄存器而不管寄存器列表中各寄存器的排列顺序、CN伪操作用来为一个协处理器的寄存器定义名称、CP伪操作用来为一个协处理器定义名称、DN伪操作用来为一个双精度的VFP寄存器定义名称、SN伪操作用来为一个单精度的VFP寄存器定义名称、FN为一个FPA浮点寄存器定义名称。
  3. 数据定义伪操作:LTONG用于声明一个数据缓冲池,ARM汇编编译器把数据缓冲池放在代码段的最后面,即下一个代码段开始之前或END伪操作之前、MAP用来定义一个结构化的内存表的首地址、FIELD用于定义一个结构化内存表中的数据域,与MAP配合使用,#是FIELD的同义词、SPACE伪操作用于分配一块内存单元并用0初始化,%是SPACE的同义词、DCB用于分配一段字节内存单元并初始化、DCD用于分配一段字内存单元并保证分配的内存是字对齐的(如果第一个字单元没有对齐则插入填补字节以保证字对齐,DCDU和DCD位移的区别是前者不要求字对齐),&是DCD的同义词、DCDO用来为基于静态基址寄存器R9的偏移量分配内存单元,这些内存单元是字对齐的(P132)、DCFD用于为双精度的浮点数分配字对齐的内存单元并初始化(DCFDU与其的区别在于不要求字对齐)、DCFS用于为双精度的浮点数分配字对齐的内存单元并初始化(DCFSU与其的区别在于不要求字对齐)、DCI用于分配一段字对齐的字内存单元(ARM中该指令分配字单元,在Thumb中分配半字对齐的半字单元),并按照后面的表达式初始化,DCI分配的内存中的数据被标识为指令、DCQ与DCQU分配8字单元、DCW和DCWU分配半字单元。
  4. 汇编控制伪操作:IF ELSE及ENDIF(可以嵌套使用)、WHILE WEND(可以嵌套使用)、MACRO MEND用来定义一段代码,称为宏定义体,这样程序就可以通过宏指令多次调用该代码段了($label中的$标识程序被汇编时将使用相应的值来代替$后的符号,P137)、MEXIT用于从宏中跳出去。
  5. 信息报告伪操作:ASSERT用于保证源程序被汇编时满足相关的条件,若不满足则报告错误类型并终止汇编、INFO支持在第一遍扫描或者第二遍扫描时报告诊断信息(在ARM汇编中,第一遍扫描和第二遍扫描是编译器在处理源代码时的两个阶段,第一遍扫描主要是为了收集跳转关系和建立符号表,解决跳转地址未知的问题;而第二遍扫描则是根据第一遍扫描的结果,填充跳转地址,生成最终的机器码)、OPT可以在源程序中设置列表选项(P140)、TLL用于在列表文件的每一页插入一个标题、SUBT用于在列表文件的每一页插入子标题。
  6. 其他伪操作:CODE16和CODE32分别用于告诉汇编编译器后面的指令为Thumb指令和ARM指令,该伪操作本身并不进行程序状态的切换,即不改变CPSR寄存器的T位、EQU用于给数字常量,基于寄存器的值和程序中的标号定义一个字符名称,相当于C语言中的#define,*是EQU的同义词(P142)、AREA用于定义一个代码段或者数据段,一个汇编程序至少包含一个段,一个大的程序可以包含多个代码段和数据段(具体段的属性设置见P143)、ENTRY指定程序的入口点、END告诉编译器已经到了源程序的结尾、ALIGN通过添加补丁字节使当前位置满足一定的对齐方式(ARM汇编中,大多数情况下,指令确实是按照字4字节对齐的。这意味着指令的地址通常应该是4的倍数)、EXPORT和GLOBAL声明一个符号可以被其他文件引用、IMPORT告诉编译器当前符号不是在本源文件中被定义的,而是在其他源文件中定义,本源文件可能引用该符号,而且不论本源文件有没有实际引用该符号,该符号都被加入到本源文件的符号表中、EXTERN告诉编译器当前符号不是在本源文件中被定义的,而是在其他源文件中定义,本源文件可能引用该符号,若本源文件没有实际引用该符号,该符号不会被加入到本源文件的符号表中、GET和INCLUDE用于将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理、INCBIN将一个文件包含到当前源文件(常常是目标文件),被包含的文件不进行汇编处理、KEEP告诉编译器将局部符号包含在目标文件的符号表中、NOFP可禁止源程序中包含浮点运算指令、REQUIRE指定段之间的相互依赖关系、REQUIRE8及PRESERVE8指示当前代码中要求数据栈8字节对齐、RN为寄存器定义一个新名称、ROUT用于定义局部变量的有效范围(若没有用ROUT,默认的局部变量作用范围为其所在段AREA)。
  7. ARM汇编语言伪指令:这些伪指令并不是真正的ARM或Thumb指令,这些指令在编译器对源程序进行汇编处理时被替换成对应的ARM或Thumb指令。这些伪指令有:ADR(小范围的地址读取伪指令,会被替换成1条指令)用于将基于PC的地址值或基于寄存器的地址值读取到寄存器中、ADRL(中等范围的地址读取伪指令,会被替换成2条指令)用于将基于PC的地址值或基于寄存器的地址值读取到寄存器中、LDR(大范围的地址读取伪指令)将一个32位常数或者一个地址值读取到寄存器中,若该地址值没有超过MOV和MVN指令的取值范围编译器会用一条合适的MOV或MVN指令代替该条伪指令,若该地址值超过MOV和MVN指令的取值范围编译器将该常数放在数据缓冲区中同时用一条基于PC的LDR指令读取该常数、NOP空操作伪指令(将被替换成ARM空操作)。
  8. ARM汇编语句格式:续航符\;以#开头加数字表示立即数;符号(symbol):符号必须从一行的行头开始,并且符号中不能包含空格,符号可以代表地址、变量、常量和数字常量。当符号代表地址时,又称为标号,当标号以数字开头时,其作用范围为当前段,这种标号又称为局部标号(只有局部标号可以以数字开头)。在进行大小比较时,编译器认为数字常量都是无符号的,所以-1>0。如果变量前有一个$符号,则汇编器在汇编时将会进行变量替换(数字变量会被替换成等值的十六进制的串),可以用$$来表示$,用.来表示变量名称的结束(P155);ARM汇编语言中的表达式:1字符串表达式:相应的字符串操作符有LEN返回字符串长度、CHR将0~255之间的整数作为含一个ASCII字符大的字符串、STR将一个数字量或逻辑表示转换为字符串(对于32位的数字而言会被转换成8个十六进制数组成的串)、LEFT返回字符串最左端一定长度的子串、RIGHT返回字符串最右端一定长度的子串、CC用于连接两个字符串(P158)。2数字表达式:数字表达式表示的是一个32位的整数。相应的数字表达操作符有NOT按位取反、(+、-、*、/、MOD)、(ROL、ROR、SHL、SHR)、(AND、OR、EOR)。3基于寄存器和基于PC的表达式:相应操作符有BASE返回基于寄存器的表达式中的寄存器编号、INDEX返回基于寄存器的表达式相对于其基址寄存器的偏移量、(+、-,即正负号)(P160)。4逻辑表达式:相应操作符有关系操作符(>、<、=等等)、逻辑操作符(LNOT、LAND、LOR、LEOR)。5其他的一些操作符:?A返回符号A的代码行所生成的可执行代码的字节数、DEF判断某个符号是否已经定义(P162);ARM汇编语言程序的格式:ARM汇编语言以段为单位组织源文件,段是相对的、具有特定名称的、不可分割的指令或数据序列,段又可以分为数据段和代码段,代码段存放执行代码,数据段存放代码运行时需要用到的数据。在ARM汇编程序中,子程序的调用是通过BL指令完成的;ARM汇编编译器为ARMASM,具体使用方法见P1。
第五章 ARM的存储系统
  1. 用于存储管理的协处理器CP15(有16个寄存器):MCR和MRC指令可以在处理器和协处理器的寄存器之间传送数据,但只能在处理器模式是系统模式时执行(P176)。寄存器C0中存放的是ARM相关的一些标识符,寄存器C1是一个控制寄存器,可以控制禁止/使能MMU以及其他的与存储相关的功能,还可以配置存储系统以及ARM处理器中的相关部分的工作方式,具体见P185。
  2. 存储管理单元MMU主要完成以下工作:虚拟存储空间到物理存储空间的映射、存储器访问权限的控制、设置虚拟存储空间的缓冲的特性。
  3. ARM中MMU的地址转换过程见P190,ARM中的存储访问失效见P201页。高速缓冲存储器Cache和写缓冲器的工作原理及地址映像和变换方法见P208页。
  4. 快速上下文切换(FCSE):通常情况下,如果两个进程占用的虚拟地址空间有重叠,系统在这两个进程之间进行切换时,必须进行虚拟地址到物理地址的重映射,会造成极大的开销,FCSE避免了这种开销,它位于CPU和MMU之间。在ARM中4GB的虚拟地址空间被分成了128个进程的地址空间块,每个进程空间块大小为32MB,每个进程空间块可以包含一个进程,系统的128个进程空间编号为0~127,编号为I的进程实际使用的虚拟地址空间为IX32MB~(I+1)X32MB-1(P218),按照进程PID的前7位进行虚拟地址空间映射,这样就减少了虚拟地址到物理地址的重映射的次数。
  5. 当用户读取PC寄存器的值时,返回的是当前指令下面第二条指令的地址,对于ARM指令来说返回当前地址值加8个字节,对于Thumb指令来说返回当前地址值加4个字节。
  6. 在ARM中,IMB通常指的是 "Instruction Memory Barrier",即指令内存屏障。这是一种用于确保指令顺序执行的机制,特别是在多核处理器或多线程环境下,可以用来确保程序的正确性和稳定性。IMB 的作用是在处理器执行指令时,确保之前的指令已经被加载到处理器中,并且相关的缓存或者················寄存器已经更新。这样可以避免指令乱序执行或者数据一致性的问题,提高程序的可靠性(P224)。
  7. 在ARM中,I/O操作通常被映射成存储器操作,I/O的输出操作可以通过存储器写入操作实现,I/O的输入操作可以通过存储器读取操作实现。
第六章 ATPCS介绍
  1. ATPCS就是ARM程序和Thumb程序中子程序调用的基本规则,这些基本规则包括寄存器的使用规则、数据栈的使用规则、参数的传递规则,有调用关系的所有子程序必须遵守同一种ATPCS。基本的ATPCS包括寄存器的使用规则、数据栈的使用规则(一般采用FD,即FULL栈、DESCENDING栈,P244)、参数传递规则。还有其他特定的ATPCS是在基础的ATPCS上扩展的,具体见P246。
第七章 ARM程序和Thumb程序混合使用
  1. 对于C/C++源程序而言,只要在编译时指定-apcs /interwork选项,编译器生成的代码会自动遵守支持ARM程序和Thumb程序混合使用的ATPCS。对于汇编源程序而言,必须保证编写的代码遵守支持ARM程序和Thumb程序混合使用的ATPCS(P250)。
  2. 可以实现程序执行状态转换的指令有:BLX、LDR、LDM、POP(后面三个指令通过向PC寄存器赋值实现执行状态切换,P254)。与程序执行状态切换有关的伪操作:CODE16、CODE32。
  3. 在ARM中,veneers指的是用于解决不同指令集或者功能版本之间的兼容性问题。可以利用veneers实现汇编程序间的程序状态切换,也可以利用veneers实现汇编程序与C/C++程序之间的程序状态切换(P261)。
第八章 C/C++以及汇编语言的混合编程
  1. 使用内嵌汇编可以在C/C++源程序中直接使用大部分的ARM指令和Thumb指令,以实现C/C++语言不能够完成的一些操作,同时程序的代码效率也比较高。
  2. 在C语言程序中使用__asm来标识一段汇编指令程序,如果一行有多个汇编指令,指令之间用分号隔开,如果一条指令占多行,要使用续行符\,在汇编指令段可以使用C语言的注释语句。还可以使用asm来标识一段汇编指令程序,具体见P266。
  3. 汇编语言、C、C++相互之间的调用见P271。
第九章 异常中断处理
  1. 当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执行。当异常中断处理程序执行完成后,程序返回到发生中断的指令的下一条指令处执行。在进入异常中断处理程序时,要保存被中断的程序的执行现场,在从异常中断处理程序退出时,要恢复被中断的程序的执行现场。
  2. 中断向量表中指定了各异常中断及其处理程序的对应关系,它通常存放在存储地址的低端。在ARM体系中,异常中断向量表的大小为32字节,其中每个异常中断占据4个字节,还保留了4个字节的空间(一共七种异常中断)。每个异常中断对应的中断向量表的4字节的空间中存放了一个跳转指令或者一个向程序计数器(PC)中赋值的数据访问指令,通过这两种指令,程序将跳转到相应的异常中断处理程序处执行。
  3. ARM体系共有七种异常中断:复位(Reset,优先级1,优先级最高,处于模式)、未定义的指令(Undefined Istruction,优先级6,优先级最低,处于未定义指令(中止)模式)、软件中断(SWI,优先级6,优先级最低,处于模式)、指令预取中断(Prefetch Abort,优先级5,处于(数据访问)中止模式)、数据访问中止(Data Abort,优先级2,处于(数据访问)中止模式)、外部请求中断(IRQ,优先级4,处于(外部中断模式)、快速中断请求(FIQ,优先级3,处于快速中断模式)。正常的应用程序运行在用户模式下(P278)。
  4. ARM处理器的异常响应过程见P279。ARM从异常中断处理程序返回过程见P282(复位异常不用返回)。
  5. SWI异常中断处理程序:通过SWI异常中断用户模式的应用可以调用系统模式下的代码,在实时操作系统中通常使用SWI异常中断为用户应用程序提供系统功能调用。在SWI指令中包括一个24位的立即数,该立即数指示了用户请求的特定的SWI功能,在SWI异常中断处理程序中要读取该24位的立即数,通过读取SWI异常模式下寄存器LR的值并从存储器相应位置读取该SWI指令即可获得这个24位立即数(在进入SWI后LR指向返回地址也就是SWI指令的下一条指令),通常SWI异常中断处理程序分为两级,第一级用于确定SWI指令中这个24位立即数,第二级具体实现相应的SWI功能(P288)。
  6. FIQ和IRQ异常中断处理程序:ARM提供的FIQ和IRQ异常中断用于外部设备向CPU请求中断服务。这两个异常中断的引脚都是低电平有效的。当前程序状态寄存器CPSR的I控制位可以屏蔽这两个异常处中断请求:当程序状态寄存器CPSR中的I控制位为1时,FIQ和IRQ异常中断被屏蔽;当程序状态寄存器CPSR中的1控制位为0时,CPU正常响应FIQ和IRQ异常中断请求。FIQ异常中断为快速异常中断,它比IRQ异常中断优先级高,这主要表现在如下两个方面:当FIQ和IRQ异常中断同时产生时,CPU先处理FIQ异常中断;在FIQ异常中断处理程序中,IRQ异常中断被禁止。由于FIQ异常中断通常用于系统中对于响应时间要求比较苛刻的任务,ARM体系在设计上有一些特别的安排,以尽量减小FIQ异常中断的响应时间。FIQ异常中断的中断向量为0x1c,位于中断向量表的最后。这样FIQ异常中断处理程序可以直接放在地址0x1c开始的存储单元,这种安排省掉了中断向量表中的跳转指令,从而也就节省了中断响应时间(P298)。
第十章 ARM C/C++编译器
  1. 编译器种类如下:armcc将C源文件编译成32位ARM代码,tcc将C源文件编译成16位Thumb代码,armcpp将C++源文件编译成32位ARM代码,tcpp将C++源文件编译成16位Thumb代码。
  2. ARM编译器文件搜索路径规则(P306)、ARM编译器命令行格式(P306)、ARM编译器的编译器指示(如指定优化级别等,P319)、ARM编译器特定的关键字(如:_asm用于告诉编译器下面的代码是汇编语言编写的,register声明寄存器变量,_int是long long的同义词等等,P333)、·ARM编译器支持的基本数据类型(P335)、ARM编译器中的预定义宏(P337)、ARM中的C/C++库。
第十一章 ARM 链接器
  1. ARM中的各种源文件(包括汇编程序、C语言程序以及C++程序)经过ARM编译后,生成ELF格式的目标文件。这些目标文件和相应的C/C++运行时库经过ARM处理后,生成ELF格式的映像文件(Image)。这种ELF格式的映像文件可以被写入设备的ROM中。
  2. ARM链接器armlink(P351)、ARM链接器生成的符号(P353)、链接器优化功能(P354)、运行时库的使用(P355)。·
  3. semihosting:该技术将应用程序中的I/O请求通过一定的通道传送到主机(Host),由主机上的资源响应应用程序的I/O请求,而不是像通常那样由应用程序所在的计算机响应应用程序的I/O请求(P388)。

因篇幅问题不能全部显示,请点此查看更多更全内容