版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、一、二进制1.1 莱布尼茨发明了二进制,并初步判断了二进制可以用于计算。布尔提出了布尔代数,说明了二进制的运算规则,可以用来进行任何计算。1.2 在数字电路这门课程中,可以看到,使用电子器件很容易实现二进制及其运算。二、对计算机的认识2.1 计算机,实际是一种自动化计算装置,其历史悠久。2.2 现代计算机,是冯.诺依曼在前人经验上提出的。他将计算机划分为五个组成部分:运算器、控制器、存储器、输入设备、输出设备。运算器和控制器组成了CPU。这种组成结构,被称为冯.诺依曼体系结构。其关键为:2.2.1 程序存放在存储器2.2.2 控制器起着全局控制管理作用。2.2.3 从存储器中,取出一条指令,送
2、到运算器中进行处理。周而复始,直到最后一条指令执行完毕。三、对CPU的认识3.1 CPU内部包括了许多部件,比较重要的有ALU、CU、流水线、缓存、片内总线、ICE、寄存器。这些部件,有些是程序员在工作中所特别关心的(称之为可见的、不透明的)。3.2 对于绝大多数程序员来说,主要关心的是寄存器及其功能作用。对于系统程序员来说,他们还要关心MMU,cache,TCM。3.3 不同体系结构的CPU,寄存器的类型与作用有所不同。3.4 对于ARM CPU来说,寄存器分为:通用寄存器、状态与控制寄存器(程序状态寄存器)、指令指针寄存器(程序计数器)。3.5 ARM CPU共有37个寄存器(32位):3
3、1个通用寄存器,6个状态寄存器。3.6 通用寄存器的作用:存放数据。这个数据,分为两种类型:第一种是直接进行算术逻辑运算的数据;第二种,是数据在存储器的位置或地址(在C语言中,又叫做指针)。3.7 状态与控制寄存器(程序状态寄存器)的作用:当CPU进行一次计算后,得到一个结果。这个结果对CPU后续的运行有影响。因此,状态与控制寄存器就必须把影响给记录下来。3.8 指令指针寄存器(程序计数器)的作用:下一条要运行的指令在存储器的位置(地址)。3.9 ARM CPU可以工作在7种工作模式之一:用户、系统、管理、中止、未定义、中断、快中断。管理、中止、未定义、中断、快中断这5种合称为异常模式。除了用
4、户模式以外,其它6种模式合称为特权模式。将CPU的工作模式进行细分,是为了保护系统的安全性,提高系统的性能。3.10 R0R7、R15,是7个工作模式所共用的。3.11 R8R12,有2套,快中断使用1套,其它6个工作模式共用1套。3.12 R13R14,共有6套,用户模式和系统模式共用1套,其它每个工作模式分别使用1套。3.13 CPSR,只有1个,由所有的工作模式所共用。3.14 SPSR,有5个,管理、中止、未定义、中断、快中断这5个工作模式各自有1个。3.15 子程序间通过寄存器R0R3来传递参数。这时,寄存器R0R3可记作a0a3。3.16 在子程序中,使用寄存器R4R11来保存局部
5、变量。这时,寄存器R4R11可以记作v1v8。3.17 寄存器R12用作过程调用中间临时寄存器,记作IP。3.18 寄存器R13用作堆栈指针,记作SP。3.19 寄存器R14称为连接寄存器,记作LR。它用于保存子程序的返回地址。3.20 寄存器R15是程序计数器,记作PC。四、对存储器的认识4.1 在冯.诺依曼体系结构中,程序和数据是存放在存储器中的。4.2 这个存储器就是我们常说的内存。4.3 在物理上,如果把程序和数据分别放在不同的存储器中,那么得到哈佛结构。4.4 由于计算机只能处理二进制,因此存放在存储器中的程序和数据都是以二进制形式存在的。4.5 在计算机组成原理中,我们知道,存储器
6、与CPU是通过总线连接起来的。而且,存储器本身有很多的组合方式。4.6 不过,对于程序员来说,在绝大多数场合中,我们都认为存储器的基本单位是1个字节(8 bit),或称为一个存储单元。4.7 存储单元可以比做房间,存储单元里面的内容就是房间里面的人。4.8 现在,对于每个存储单元,分别给一个编号(类似于房间号码)。这个编号,我们称之为地址(在语言中,又称为指针)。4.9 编号的范围,不同的CPU有不同的规定。4.10 对于32位ARM CPU,编号范围为0到232-1。这个范围称为地址空间。显然,这个空间是一维的线性空间。4.11 连接存储器与CPU的硬件线路分为:数据总线、地址总线、控制总线
7、。4.12 我们说一个ARM CPU是32位的,那么数据总线共32根。一次可以读取32bit数据,即4个字节。当然,也可以只读取1个字节,2个字节(半字)。4.13 不管是冯.诺依曼体系结构还是哈佛结构,程序和数据的地址都是处于同一个地址空间。五、对外设的认识5.1 CPU的速度远远大于外设的速度。5.2 外设的种类非常多:按传输的数值类型来划分,可以分为模拟量和数字量;按一次传输数据的数量来划分,可以分为串行和并行;按对总线的占用方式来划分,可以划分为独占式(点对点式)和共享式。5.3 为了保证兼容性、通用性、速度匹配,在CPU和外设之间专门设置一种电路部件,这种电路部件被称为接口电路。简称
8、为接口。5.4 通过接口,实现CPU与外设之间的数据传输,对外设进行控制,检测外设的状态。5.5 跟存储器一样,每个接口都有一个编号。同样地,这个编号被称为地址(接口地址)。5.6 与存储器的存储单元的编号一样,全部的接口编号也形成一个地址空间。5.7 如果存储器的地址空间与接口的地址空间是独立的,那么,所得到的地址编址方案叫做独立编址。5.8 如果把存储器的地址空间与接口的地址空间整合在一起,那么,所得到的地址编址方案叫做统一编址。5.9 ARM CPU采用了统一编址方案。六、ARM CPU指令的认识6.1 ARM CPU有两大类指令,一个就叫做ARM指令集,另一种叫做Thumb指令集。6.
9、2 我们主要学习ARM指令集。6.3 ARM CPU是一种RISC CPU,一条ARM指令占用了4个字节,即32bit。6.4 ARM指令的汇编语言格式为:<opcode> <cond> S <Rd> ,<Rn>,<operand2>6.4.1 <>号内的项是必需的,号内的项是可选的。例如,<opcode>是指令助记符,这是必需的。6.4.2 <cond>为指令执行条件,是可选项。若不书写则使用默认条件AL(无条件执行)。opcode指令助记符,如LDR、STR等。cond执行条件,如EQ、NE等。
10、S是否影响CPSR寄存器的值,书写时影响CPSR。Rd目标寄存器。Rn第1个操作数的寄存器。operand2第2个操作数。6.5 条件码的实例6.6 ARM存储器访问指令6.6.1 ARM处理器是加载/存储体系结构的典型的RISC处理器,对存储器的访问只能使用加载和存储指令实现。6.6.2 ARM的加载/存储指令实现字、半字、无符号/有符号字节操作;多寄存器加载/存储指令可实现一条指令加载/存储多个寄存器的内容,大大提高效率。6.6.3 SWP指令是一条寄存器和存储器内容交换的指令,可用于信号量操作等。七、ARM CPU的寻址方式7.1 实际上,在存储器中的ARM指令是一个32bit的二进制,
11、包含两个基本部分(字段):操作码和地址码。7.2 操作码表明ARM指令的功能7.3 地址码表明数据存放在哪个地方。数据可以存放于存储器、寄存器、也可以直接跟在操作码后面。7.4 所谓寻址方式,就是根据指令中的地址码去寻找真实操作数地址的方式。7.5 ARM指令集具有9种寻址方式。7.5.1 寄存器寻址。操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值来操作。例如:MOV R1, R2 ; 将R2的值存入R17.5.2 立即寻址。指令中的操作码字段后面的地址码部分就是操作数。也就是说,指令已经包含了数据,当CPU从存储器中取出指令时,也就取出了可以立即使用的
12、操作数(这样的数称为立即数)。例如:MOV R0, #0xFF00; 将立即数0xFF00装入R0寄存器SUBS R0, R0, #1 ; R0 减1,结果放入R0,并且影响标志位立即数前面需加“#”号;表示16进制数值时以“0x”表示7.5.3 寄存器移位寻址。这是ARM指令集特有的寻址方式。当第2个操作数是寄存器移位方式时,第2个寄存器操作数在与第1个操作数结合之前,选择进行移位操作。例如:MOV R0, R2, LSL #3 ; R2的值左移3位,结果放入R0,即是R0=R2×8ANDS R1, R1, R2, LSL R3 ; R2的值左移R3位,再和R1进行“与”操作,;
13、结果放入R17.5.4 寄存器间接寻址。地址码是某个通用寄存器的编号,所需的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针。LDR R1, R2 ; 将R2指向的存储单元的数据读出,保存在R1中7.5.5 基址寻址。将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址。基址寻址用于访问基址附近的存储单元,常用于一组数据的操作(数组、表)、功能部件寄存器访问等。例如:LDR R2, R3,#0x0C ;读取R3+0x0C地址上的存储单元的内容,放入R2STR R1, R0,#-4! ;先R0=R0-4,然后把R1的值寄存到保存到R0指定的存储单元符号“!”表明指令
14、在完成数据传送后更新基址寄存器。7.5.6 多寄存器寻址。一次可传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器。例如:LDMIA R1!, R2-R7, R12 ;将R1指向的单元中的数据读出到R2R7、R12中,R1自动加1STMIA R0!, R2-R7, R12 ;将寄存器R2R7、R12的值保存到R0指向的存储单元中,R0自动加1使用多寄存器寻址指令时,寄存器子集的顺序是由小到大的顺序排列,连续的寄存器可用“-”连接,否则用“,”分隔书写。7.5.7 堆栈寻址。堆栈是一种按特定顺序进行存取的存储区,操作顺序分为“后进先出”或“先进后出”。7.5.7.1 堆栈寻址使
15、用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元即是堆栈的栈顶。7.5.7.2 存储器堆栈可分为两种:² 向上生长:向高地址方向生长,称为递增堆栈。² 向下生长:向低地址方向生长,称为递减堆栈。7.5.7.3 堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个待压入数据的空位置,称为空堆栈。这样就有4种类型的堆栈表示递增和递减的满和空堆栈的各种组合:² 满递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的最高地址。指令如LDMFA、STMFA等。² 空递增:堆栈通过增大存储器的地址向上增长
16、,堆栈指针指向堆栈上的第一个空位置。指令如LDMEA、STMEA等。² 满递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址。指令如LDMFD、STMFD等。² 空递减:堆栈通过减小存储器的地址向下增长,堆栈指针向堆栈下的第一个空位置。指令如LDMED、STMED等。7.5.7.4 堆栈寻址指令举例如下:STMFD SP!, R1-R7, LR ; 将R1R7、LR入栈。满递减堆栈。LDMFD SP!, R1-R7, LR ; 数据出栈,放入R1R7、LR寄存器。满递减堆栈。7.5.8 块拷贝寻址。适用于多寄存器传送指令,用于将一块数据从存储器的某
17、一位置拷贝到另一位置。例如:STMIA R0!, R1-R7 ; 将R1R7 的数据保存到存储器中。存储指针在保存第一个值之后增加,增长方向为向上增长。STMIB R0!, R1-R7 ; 将R1R7 的数据保存到存储器中。存储指针在保存第一个值之前增加,增长方向为向上增长。STMDA R0!, R1-R7 ; 将R1R7 的数据保存到存储器中。存储指针在保存第一个值之后增加,增长方向为向下增长。STMDB R0!, R1-R7 ; 将R1R7 的数据保存到存储器中。存储指针在保存第一个值之前增加,增长方向为向下增长。7.5.9 相对寻址。基址寻址的一种变通。由程序计数器PC提供基准地址,指令
18、中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。例如:八、关于移位操作8.1 移位操作有5种,如下图所示。其实,C语言就有移位运算符。8.2 LSL:逻辑左移(Logical Shift Left),寄存器中字的低端空出的位补0。8.3 LSR:逻辑右移(Logical Shift Right),寄存器中字的高端空出的位补0。8.4 ASR:算术右移(Arithmetic Shift Right),移位过程中保持符号位不变,即若源操作数为正数,则字的高端空出的位补0,否则补1。8.5 ROR:循环右移(Rtate Right),由字的低端移出的位填入字的高端空出的位。8.6
19、 RRX:带扩展的循环右移(Rotate Right eXtended by 1 place),操作数右移一位,高端空出的位用原C标志值填充。九、ARM指令集编码中的第2操作数9.1 ARM指令的汇编形式,如下所示:<opcode> <cond> S <Rd>, <Rn>, <operand2>9.2 ARM指令编码格式(32位),如下图所示9.3 第2操作数“operand2”。可提高代码效率,形式如下:9.3.1 #immed_8r常数表达式,得到一个32位的立即数,但并不是所有的32位立即数都是有效的。从下图可以看出,opera
20、nd2由两部分组成,右边的一部分是8位立即数,左边部分是循环右移长度(或次数)。通过对右边部分进行指定长度的循环右移,可以得到32位的立即数。不过,这种运算所能得到的32位立即数是很少的。例如:MOV R4, #0x8000000A。0x8000000A是由8位的0xA8循环右移0x4位得到。9.3.2 Rm寄存器方式;在寄存器方式下,操作数即为寄存器的数值。例如:SUBR1, R1, R29.3.3 Rm, shift寄存器移位方式;将寄存器的移位结果作为操作数(移位操作不消耗额外的时间),但Rm值保持不变。9.3.4 shift,是移动次数(位数)。移动方式,已经在第八部分“关于移位”讲到
21、。移动次数的取值范围为:n 5bit的立即数n 寄存器9.3.5 例如:ADDR1, R1, R1, LSL #3;R1=R1+R1<<3SUBR1, R1, R2, LSR R3;R1=R1-R2>>R39.4 CPSR与SPSR十、关于ARM的指令10.1 ARM指令集大致分为6类:分支指令、Load/Store指令、数据处理指令、程序状态寄存器指令、异常中断指令、协处理器指令。10.2 分支指令。ARM有两种方法可以实现程序分支转移。n 跳转指令。n 长跳转。直接向PC寄存器(R15)中写入目标地址。10.2.1 跳转指令有4种:B、BL、BX、BLX。10.2.
22、2 B分支指令,语法:Bcond label10.2.3 BL带链接分支指令,语法:BLcond label10.2.4 BX分支并可选地交换指令集,语法:BXcond Rm10.2.5 BLX带链接分支并可选择地交换指令集,语法:BLXcond label | Rm10.2.6 BL指令的意义:Branch and Link。例如:. .bl MyPro;调用子程序MyPro.MyPro;子程序MyPro本体 . . mov PC, LR;将R14的值送入R15,返回10.2.7 BX指令使用举例。通过使用BX指令可以让ARM处理器内核工作状态在ARM状态和Thumb状态之间进行切换。;从A
23、RM状态转变为Thumb状态LDRR0, =Sub_Routine+1BXR0;从Thumb 状态转变为ARM状态LDRR0, =Sub_RoutineBXR010.2.8 长跳转。直接向PC寄存器写入目标地址值,可以实现4GB地址空间中的任意跳转。例如,以下的两条指令实现了4GB地址空间中的子程序调用:MOV LR, PC;保存返回地址MOV R15, #0x00110000;无条件转向绝对地址0x110000;此32位立即数地址应满足单字节循环右移偶数次10.3 Load/Store指令,又称为数据加载与存储指令。l 用于在存储器和处理器之间传输数据。Load用于把内存中的数据装载到寄存器
24、,Store指令用于把寄存器中的数据存入内存。l 同时,由于ARM CPU采用统一编址,因此,外围I/O也使用Load/Store指令。10.3.1 共有3种类型的Load/Store指令:n 单寄存器传输指令n 多寄存器传输指令n 交换指令10.3.2 Load/Store指令变址模式。变址模式有四种:零偏移、前变址、后变址、回写前变址。显然,变址的作用等效于C语言中的指针。变址模式数据基址寄存器指令举例零偏移membase直接基址寄存器寻址LDR r0, r1回写前变址membase+offset基址寄存器加偏移量LDR r0, r1, #4!前变址membase+offset不变LDR
25、r0, r1, #4后变址membase基址寄存器加偏移量LDR r0, r1, #410.3.3 单寄存器传送指令助记码操作指令描述LDR把一个字装入一个寄存器Rdmem32addressSTR从一个寄存器保存一个字Rdmem32addressLDRB把一个字节装入一个寄存器Rdmem8addressSTRB从一个寄存器保存一个字节Rdmem8addressLDRH把一个半字装入一个寄存器Rdmem16addressSTRH从一个寄存器保存一个半字Rdmem16addressLDRSB把一个有符号字节装入寄存器Rd符号扩展(mem8address)LDRSH把一个有符号半字装入寄存器Rd符号
26、扩展(mem16address)10.3.4 单寄存器传送指令,以LDR和STR为例LDR R2,R3,#0x0C 读取R30x0C地址上的一个字数据内容,放入R2。属前变址。STR R1,R0,#4! R04R1,R0=R04符号“!”表明指令在完成数据传送后应该更新基址寄存器;属回写前变址。LDR R1,R0,R3,LSL #1 将R0R3×2地址上的存储单元的内容读出,存入R1。LDR R3, STARTSTART代表着子程序的偏移地址。ARM CPU自动将偏移地址与程序计数器PC的值进行相加。PC,是隐含的基址寄存器,代表着当前正在执行的指令。10.3.5 多寄存器传输指令。
27、前面第七部分的多寄存器寻址方式已经讲过了。10.3.6 交换指令。SWP,可以一次性地完成数据交换。10.4 数据处理指令10.4.1 数据处理指令对存放在寄存器中的数据进行操作,分为:数据传送指令、算术指令、逻辑指令、比较指令和乘法指令。10.4.2 算术指令和逻辑运算指令完成常用的算法与逻辑运算,将运算结果保存于目的寄存器中,同时更新CPSR 的相应条件标志位。10.4.3 比较指令不保存运算结果,只更新CPSR中相应的条件标志位。10.4.4 ARM数据处理指令机器编码格式如下图所示:11.4.4.1 cond: 指令执行的条件码。跟上一条指令有关。11.4.4.2 I:用于区别第二操作
28、数据是立即数(I=1)还是寄存器移位(I=0)11.4.4.3 opcode:数据处理指令操作码。11.4.4.4 S:用于设置条件码,S=0,条件码不改变,S=1,条件码根据具体指令的结果修改。11.4.4.5 Rn:第一操作数寄存器。11.4.4.6 Rd:目标寄存器。11.4.4.7 operand2:第二操作数,该数可以是立即数或寄存器移位数。10.4.5 数据传送指令11.4.5.1 将一个寄存器中的数据传送到另一个寄存器,或者将一个立即数传送到寄存器。11.4.5.2 通常用来设置寄存器的初始值。11.4.5.3 数据传送指令包括:² MOV数据传送指令² MV
29、N数据取反传送指令11.4.5.4 实例:10.4.6 移位操作10.4.6.1 ARM微处理器一个显著的特征是:在操作数进入ALU之前,对操作数进行预处理。10.4.6.2 如:指定位数的左移或右移,这种功能明显增加了数据处理操作的灵活性。10.4.6.3 移动操作包括:LSL逻辑左移LSR逻辑右移ASR算术右移ROR循环右移RRX带扩展的循环右移10.4.6.4 例:设指令操作之前,R0=0x00000000, R1=0x80000004,则执行如下指令后R0, R1的值有什么变化?MOVR0, R1, LSL #1分析:该指令的作用是将R1中的内容左移一位后传送到R0中。指令执行时,首先
30、实现R1, LSL #1,即将R1的内容左移一位,得到8。然后该值送入R0,故R0中的值为0x00000008,R0中原来的值被覆盖掉,R1的值仍为0x80000004。10.4.7 算术指令10.4.7.1 主要是加法和减法。10.4.7.2 两个32位数据的加减操作。10.4.7.3 与第二操作数结合起来,更加灵活。10.4.7.4 主要包括:ADD 加法指令ADC 带进位加法指令SUB 减法指令SBC 带借位减法指令RSB 逆向减法指令RSC 带借位的逆向减法指令10.4.7.5 以ADD为例:² 汇编格式:ADD <cond> S Rd, Rn, operand2
31、² 寄存器Rn的值和操作数operand2相加,结果送Rd寄存器,即Rd=Rn+operand2。² Rd为操作数1,要求是一个寄存器。² operand2是操作数2,可以是一个寄存器,被移位的寄存器或一个立即数。² S选项影响CPSR中条件标志位的值:N、Z、C、V标志。² 示例:10.4.8 逻辑运算指令10.4.8.1 对操作数进行按位操作。10.4.8.2 位与位之间无进位或借位。10.4.8.3 没有数的正负与数的大小之分。10.4.8.4 主要包括:10.4.8.5 以AND指令为例:10.4.9 比较指令10.4.9.1 将一个寄
32、存器与一个32位的值进行比较或测试。10.4.9.2 根据结果更新CPSR中的标志位,但不影响其他的寄存器。10.4.9.3 在设置标志位后,其他指令可以通过条件执行来改变程序的执行顺序。10.4.9.4 对于比较指令,不需要使用S后缀就可以改变标志位的值。10.4.9.5 比较指令包括:n CMP 比较指令。n CMN 反值比较指令。n TST 位测试指令。n TEQ 相等测试指令。10.4.9.6 以CMP为例:² CMP指令将寄存器Rn的内容和另一个操作数operand2进行比较,同时更新CPSR中条件标志位的值。² 该指令实质上是进行一次减法运算,但不存储结果,只更
33、改条件标志位。后面的指令就可以根据条件标志位来决定是否执行。10.4.10 乘法指令10.4.10.1 把一对寄存器的内容相乘,然后根据指令类型把结果累加到其他的寄存器。10.4.10.2 乘法指令与乘加指令共有6条,根据运算结果可分为32位运算和64位运算两类。10.4.10.3 64位乘法又称为长整型乘法指令,由于结果太大,不能再放在一个32位的寄存器中,所以把结果存放在2个32位的寄存器Rdlo和Rdhi中。10.4.10.4 Rdlo存放结果的低32位,Rdhi存放结果的高32位。10.4.10.5 对于乘法指令,所有源操作数、目的寄存器都必须为通用寄存器,不能对操作数使用立即数或被移
34、位的寄存器。10.4.10.6 目的寄存器Rd和操作数Rm必须是不同的寄存器。10.4.10.7 乘法指令与乘加指令共有以下6条:n MUL 32位乘法指令。n MLA 32位乘加指令。n SMULL 64位有符号数乘法指令。n SMLAL 64位有符号数乘加指令。n UMULL 64位无符号数乘法指令。n UMLAL 64位无符号数乘加指令。10.4.10.8 以MUL为例:n 将操作数Rm与操作数Rs的乘法运算,并把结果放置到目的寄存器Rd中。即Rd=Rm×Rs。n S选项决定指令的操作是否影响CPSR中条件标志位的值,有S时指令执行后的结果影响CPSR中条件标志位N和Z值。n
35、在ARMv4及以前版本中,标志C和V不可靠,在ARMv5及以后版本中不影响C和V标志(其它的乘法指令对于S的规定与此相同)。10.4.11 异常中断指令SWI10.4.11.1 在ARM体系结构中,存在7种异常处理。10.4.11.2 当某种异常发生时,CPU把程序计数器PC设置为一个特定的存储器地址,这个地址存放了一条跳转指令。CPU执行这条跳转指令,就可以进入相应的中断处理服务程序的起始地址(入口),对异常进行处理。10.4.11.3 这7个异常所对应的存储器地址形成了一张表,即向量表(vector table)。10.4.11.4 向量表在ARM地址空间的位置,有两种情况,根据具体的CP
36、U来确定,如下表所示:异 常 类 型处理器模式执行低地址执行高地址复位异常(Reset)特权模式0x000000000xFFFF0000未定义指令异常(Undefined Interrupt)未定义指令中止模式0x000000040xFFFF0004软中断异常(SWI)特权模式0x000000080xFFFF0008预取异常(Prefetch Abort)数据访问中止模式0x0000000C0xFFFF000C数据异常(Data Abort)数据访问中止模式0x000000100xFFFF0010外部中断异常(IRQ)外部中断请求模式0x000000180xFFFF0018快速中断异常(FIQ
37、)快速中断请求模式0x0000001C0xFFFF001C10.4.11.5 当异常发生时,分组寄存器r14和SPSR用于保存处理器状态,操作伪指令如下: R14_<exception_mode> = return link SPSR_<exception_mode> = CPSR CPSR40 = exception mode number CPSR5 = 0 /*进入ARM状态*/ If <exception_mode> = = reset or FIQ then CPSR6 = 1 /*屏蔽快速中断FIQ*/ CPSR7 = 1 /*屏蔽外部中断IRQ
38、*/ PC = exception vector address 10.4.11.6 异常返回时,SPSR内容恢复到CPSR,连接寄存器r14的内容恢复到程序计数器PC。10.4.11.7 这里,专注于软中断异常SWI。软中断异常是程序员调用SWI指令所引起的异常。10.4.11.8 软中断异常发生时,处理器进入特权模式,执行一些特权模式下的操作系统功能。10.4.11.9 软中断异常发生时,处理器执行下列伪操作。 r14_svc = address of next instruction after the SWI instruction SPSR_und = CPSR CPSR40 = 0
39、b10011 /*进入特权模式*/ CPSR5 = 0 /*处理器进入ARM状态*/ /*CPSR6保持不变*/ CPSR7 = 1 /*禁止外设中断*/ If high vectors configured then PC = 0xffff0008 Else PC = 0x0000000810.4.11.10 为什么要设计SWI呢?原因有很多,例如:CPU可以从用户模式转移到系统模式;可以方便程序员扩充系统功能,等等。10.4.11.11 软中断异常SWI还可以进一步包含成多个特定功能。每个功能用SWI中断号进行区分。10.4.11.12 所以,当发生SWI异常,进入异常处理程序时,异常处理
40、程序必须提取SWI中断号,从而得到用户请求的特定SWI功能。10.4.11.13 SWI指令格式SWIcond immed_2410.4.11.14 在SWI指令的编码格式中,后24位称为指令的"comment field"。该域保存的24位数,即为SWI指令的中断号。10.4.11.15 下面是一个SWI的中断处理程序.SWI_Handler: STMFD sp!, r0-r12,lr ;保存寄存器 LDR r0, lr,#-4 ;计算SWI指令地址 BIC r0, r0, #0xff000000 ;提取指令编码的后24位 ; ; 提取出的中断号放r0寄存器,函数返回 ;
41、 LDMFD sp!, r0-r12,pc ;恢复寄存器在这个例子中,使用LR-4得到SWI指令的地址,再通过"BIC r0, r0, #0xff000000"指令提取SWI指令中断号。十一、ARM汇编语言程序的介绍11.1 一个最简单的程序 AREA XXH, CODE, READONLY ;声明代码段 CODE32 ;声明为32位ARM指令 ENTRY ;声明程序入口START MOV R0 ,#0 MOV R1, #1 ADD R1, R1, R0 B START END11.2 在ARM汇编程序中用“;”号进行注释。11.3 一个完整的ARM汇编由两部分组成:声明,
42、实际代码段两部分组成。11.4 声明:在一个程序之前先要进行声明11.4.1 声明代码段:用AREA指令定义一个段,说明所定义段的相关属性(说明段的名字,段的属性)11.4.2 声明ARM指令:用CODE32或CODE16来声明程序为32位ARM指令或是16位Thumb指令。11.4.3 声明程序入口:用ENTRY指令标识程序的入口点。11.4.4 在程序完成后要用END指令声明程序结束。每一个汇编程序段都必须有一条END指令,指示代码段的结束。11.5 段:在ARM汇编语言程序中,以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。11.6 段的分类11.6.1 代码段:
43、代码段的内容为执行代码11.6.2 数据段: 数据段存放代码运行时需要用到的数据。11.6.3 代码段一般具有READONLY属性。11.6.4 数据段一般具有READWRITE属性。11.6.5 一个汇编程序至少有一个代码段。如果程序较长时,可以分割为多个代码段和数据段。多个段在程序编译连接时最终形成一个可执行的映像文件。11.7 汇编语言的语句格式LABEL OPERATION OPERAND ;COMMENT11.7.1 LABEL。n 标号域用来表示指令的地址、变量、过程名、数据的地址和常量。n 语句标号必须在一行的开头书写,不能留空格。11.7.2 操作助记符域(OPERATION)
44、。n 操作助记符域可以为指令、伪操作、宏指令或伪指令的助记符。n 所有的指令都不能在行的开头书写,必须在指令的前面有空格,然后再书写指令。n 可以为大写,也可以为小写。但是,不能大小写混写。n 指令助记符和后面的操作数或操作寄存器之间必须有空格,不可以在它们之间使用逗号。n 伪操作是ARM汇编语言程序里的一些特殊助记符,其作用主要是为完成汇编程序做的各种准备工作,在源程序进行汇编时由汇编程序处理,而不是程序运行期间由机器执行。n 宏指令是一段在独立的程序代码,可插在源程序中,它通过伪操作来定义。宏在使用之前必须提前定义好,宏之间可互相调用,也可递归调用。n 伪指令是ARM汇编语言程序里的特殊指
45、令助记符,也不在程序运行期间由机器执行。它们在汇编时将被合适的机器指令代替成ARM或Thumb指令,从而实现真正的指令操作。11.7.3 操作数域(OPERAND)。操作数域表示操作的对象,操作数可以是常量、变量、标号、寄存器名或表达式,不同对象之间必须用逗号“,”分开。实例:十二、汇编语言程序中常用的符号12.1 在汇编语言程序设计中,经常使用各种符号表示变量、常量和地址等,以增加程序的可读性。12.2 符号的命名必须遵循以下约定:n 由大小写字母、数字以及下划线组成。n 区分大小写,同名的大、小写符号会被编译器认为是两个不同的符号。n 符号在其作用范围内必须唯一,即在其作用范围内不可有同名
46、的符号。n 自定义的符号名不能与系统的保留字相同。n 符号名不应与指令或伪指令同名。12.3 程序中的变量n 程序中的变量是指其值在程序的运行过程中可以改变的量。n 通过定义变量可以简化程序的表达,增强程序的可读性,方便对程序进行修改,便于交流和记忆。n 同时编译程序会自动安排变量的存储空间,程序设计工程师可以不必去关心存储空间的安排,因此一个好的程序设计工程师应该恰当地使用变量。n ARM汇编程序所支持的变量有数值变量、逻辑变量和字符串变量。n 使用GBLA、GBLL、GBLS伪操作声明全局变量。n 使用LCLA、LCLL、LCLS伪操作声明局部变量。n 使用SETA、SETL和SETS对变
47、量进行初始化。n 数值变量的值的大小不应超过一个32位数所能表示的范围。全局数值变量使用伪操作GBLA定义,局部数值变量使用伪操作LCLA定义。数值变量使用SETA赋值。n 逻辑变量。全局逻辑变量使用伪操作GBLL定义,局部逻辑变量使用伪操作LCLL定义。逻辑变量使用SETL赋值。n 字符串变量。长度不得越出512字节,最小长度为0,全局字符变量使用伪操作GBLS定义,局部字符变量使用伪操作LCLS定义,使用SETS赋值。12.4 程序中的常量n 常量,程序的运行过程中不能被改变的量。ARM汇编程序的常量:数值常量、逻辑常量、字符串常量。n 数值常量。32位整数,无符号数的取值范围为0到232
48、-1,有符号数的取值范围为-231到231-1。使用EQU定义数值常量n 十进制数:在表达式中可以直接表达,例如:1、2、233。n 十六进数:采用前缀0x,例如0x003;或者使用前缀&,例如&10F。n n进制数:n的范围为2到9,例如8_233表示一个八进制数。n ASCII的表示:熟记A、a、0、回车、换行、空格的ASCII。其用法与C语言一样。n 逻辑常量:TRUE, FALSE。注意带大括号。n 字符串常量:字符常量由单引号表示,包括C语言中的转义字符,如n。字符串常量用双引号表示,也包括转义字符,如”abcn”。12.5 汇编时变量代换n 如果在字符串变量前面有一
49、个代换操作符“$”,编译器会将该字符串变量的值代换“$”后的字符串变量。n 如果在数值变量前面有一个代换操作符“$”,编译器将该数值变量的值转换为十六进制的字符串,并将该十六进制的字符串代换“$”后的数值变量。a1 SETA 12str1 SETS “The number is $a1”则汇编后str1的值为“The number is 0000000C”n 如果在逻辑变量前面有一个代换操作符“$”,编译器会将该逻辑变量代换为它的取值(真或假)。十三、ARM汇编语言程序中的表达式和运算符n 表达式一般由变量、常量、运算符和括号构成。n 常用的表达式有数值表达式、逻辑表达式和字符串表达式。13.
50、1 数值表达式及运算符。13.1.1 数值表达式一般由数值常量、数值变量、数值运算符和括号构成。13.1.2 算术运算符13.1.3 移位运算13.1.4 位逻辑运算符13.1.5 数值表达式综合实例13.2 逻辑表达式及运算符13.2.1 逻辑表达式一般由逻辑量、逻辑操作符、关系操作符和括号构成。13.2.2 运算结果为真TRUE或假FALSE。13.2.3 关系运算符13.2.4 逻辑运算符13.3 字符串表达式及运算符13.3.1 字符串表达式一般由字符串常量、字符串变量、运算符和括号构成。13.3.2 LEN运算符。返回字符串的长度(字符数),以X表示字符串表达式,格式如下:LEN:X
51、其中,X为一个数字表达式或逻辑表达式。13.3.3 CHR运算符。将0255之间的整数转换为一个字符,以M表示某一个整数,其语法格式如下:CHR:M13.3.4 STR运算符。将一个数字表达式或逻辑表达式转换为一个字符串。对于数字表达式,STR运算符将其转换为一个以十六进制组成的字符串;对于逻辑表达式,STR运算符将其转换为字符串T或F,格式如下:STR:X其中,X为一个数字表达式或逻辑表达式。13.3.5 LEFT运算符。LEFT运算符返回某个字符串左端的一个子串,其语法格式如下:X:LEFT:Y其中:X为源字符串,Y为一个整数,表示要返回的字符个数。13.3.6 RIGHT运算符。与LEF
52、T运算符相对应,RIGHT运算符返回某个字符串右端的一个子串,其语法格式如下:X:RIGHT:Y其中:X为源字符串,Y为一个整数,表示要返回的字符个数。13.3.7 CC运算符。CC运算符用于将两个字符串连接成一个字符串,其语法格式如下:X:CC:Y其中:X为源字符串1,Y为源字符串2,CC运算符将Y连接到X的后面。13.4 与寄存器和程序计数器(PC)相关的表达式及运算符13.4.1 BASE运算符。返回基于寄存器的表达式中寄存器的编号,其语法格式如下:BASE:X其中,X为与寄存器相关的表达式。13.4.2 INDEX运算符。INDEX运算符返回基于寄存器的表达式中相对于其基址寄存器的偏移
53、量,其语法格式如下:INDEX:X其中,X为与寄存器相关的表达式。13.5 其他常用运算符n ?运算符。返回某代码行所生成的可执行代码的长度,例如:?X返回定义符号X的代码行所生成的可执行代码的字节数。n DEF运算符。DEF运算符判断是否定义某个符号,例如:DEF:X如果符号X已经定义,则结果为真,否则为假13.6 表达式中各元素运算次序的优先级n 括号运算符的优先级最高。n 相邻的单目运算符的运算顺序为从右到左,单目运算符的优先级高于其他运算符。n 优先级相同的双目运算符的运算顺序为从左到右。十四、ARM汇编语言程序中所支持的伪操作14.1 在ARM汇编语言程序里,有一些特殊指令助记符,这
54、些助记符与指令系统的助记符不同,没有相对应的操作码,通常称之为伪操作标识符(directive),它们所完成的操作称为伪操作。14.2 伪操作在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪操作仅在汇编过程中起作用,一旦汇编结束,伪操作的使命就完成。主要有:n 符号定义伪操作n 数据定义伪操作n 汇编控制伪操作n 宏指令14.3 符号定义(Symbol Definition)伪操作n 用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。n 常见的符号定义伪操作有如下几种:² 用于定义全局变量的GBLA、GBLL和GBLS。² 用于定义局部变量的LCLA、LCLL和LCLS。² 用于对变量赋值的SETA、SETL、SETS。² 为通用寄存器列表定义名称的RLIST。² 为协处理器寄存器定义别名的CN。² 为协处理器定义别名的CP。² 为VFP寄存器定义名称的DN和SN。² 为FPA浮点指针寄存器定义名称的FPA。14.3.1 全局变量定义伪操作GBLA、GBLL和GBLSGBLA Test1;定义一个全局的数字变量,变量名为Test1Test1 SETA 0xaa;将该变量赋值为0xaaGBLL Test2;定义一个全局的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年AIMES从自动化向智能化跨越实施手册
- 2026年产品绿色化:生态设计与生命周期评价应用
- 2026年混合型社区物业纠纷多发靶向治理三色管理机制设计
- 2026年浙江省杭州城区6校初三5月学情调查生物试题含解析
- 山东省枣庄2025-2026学年中考第二次模拟考试化学试题试卷含解析
- 2026年江西省萍乡市重点中学初三3月联合质量检测试题化学试题试卷含解析
- 黄山市~达标名校2025-2026学年初三下学期返校联考化学试题含解析
- 2026年【苏科版】江苏省苏州市姑苏区初三4月中考模拟(二模)生物试题含解析
- 2026年河北省沧州市献县初三下学期化学试题模拟试题含解析
- 2026届北京大兴区北臧村中学中考生物试题模拟题及解析(全国Ⅰ卷)含解析
- 山东省2026年春季高考技能测试建筑类专业模拟试题及答案解析
- 2026年学士学位英语测试题及答案
- (一模)2026年深圳市高三年级第一次调研考试政治试卷(含官方答案)
- 上海市普陀区学校(五四制)2025-2026学年六年级上学期期中语文试题(解析版)
- XX初中校长在2026年春季学期教科研工作推进会上的发言
- 2026年伊春职业学院单招职业适应性考试题库附参考答案详解(b卷)
- 城市供水排水管网养护指南
- JJF(皖) 252-2026 球压试验装置校准规范
- 2026年无锡工艺职业技术学院单招综合素质考试题库带答案解析
- 机电一体化毕业论文8000字
- 森林防火-整改方案(3篇)
评论
0/150
提交评论