嵌入式系统课件4-5

PPT
  • 阅读 219 次
  • 下载 0 次
  • 页数 263 页
  • 大小 2.278 MB
  • 2022-12-05 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档50.00 元 加入VIP免费下载
此文档由【小橙橙】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
嵌入式系统课件4-5
可在后台配置第一页与第二页中间广告代码
嵌入式系统课件4-5
可在后台配置第二页与第三页中间广告代码
嵌入式系统课件4-5
可在后台配置第三页与第四页中间广告代码
嵌入式系统课件4-5
嵌入式系统课件4-5
还剩10页未读,继续阅读
【这是免费文档,您可以免费阅读】
/ 263
  • 收藏
  • 违规举报
  • © 版权认领
下载文档50.00 元 加入VIP免费下载
文本内容

【文档说明】嵌入式系统课件4-5.ppt,共(263)页,2.278 MB,由小橙橙上传

转载请保留链接:https://www.ichengzhen.cn/view-92654.html

以下为本文档部分文字说明:

2022/12/5嵌入式系统原理及应用刘军芳14CHAPTERARM7指令集2022/12/5嵌入式系统原理及应用刘军芳2本章重点1、ARM处理器的寻址方式2、ARM指令集3、Thumb指令集2022/12/5嵌入式系统原理及应用刘军芳34.1ARM指令的分类与格式ARM

微处理器的指令集可以分为跳转(分支)指令、数据处理指令、程序状态寄存器(CPSR)处理指令、加载/存储指令、协处理器指令和异常产生指令六大类,具体的指令及功能如表4-1所示(表中指令为基本ARM指令,不包括派生的ARM指令)。2022/12/5嵌入式

系统原理及应用刘军芳42022/12/5嵌入式系统原理及应用刘军芳54.1.2指令格式用助记符表示的ARM指令一般格式如下:<opcode>{<cond>}{S}<Rd>,<Rn>{,<OP2>}(格式中<>的内容必不可少,{}中的内容可省略)<opcode>表示操作码,如ADD表

示算术加法。{<cond>}表示指令执行的条件域,如EQ、NE等,缺省为AL。{S}决定指令的执行结果是否影响CPSR的值,使用该后缀则指令执行的结果影响CPSR的值,否则不影响。<Rd>表示目的寄存器。<Rn>表示第一个操作数,为

寄存器。<op2>表示第二个操作数,可以是立即数、寄存器和寄存器移位操作数。2022/12/5嵌入式系统原理及应用刘军芳62指令的条件域当处理器工作在ARM状态时,几乎所有的指令均根据CPSR中条件码的状态和指令的条件域有条

件的执行。当指令的执行条件满足时,指令被执行,否则指令被忽略。每一条ARM指令包含4位的条件码,位于指令的最高4位[31:28]。条件码共有16种,每种条件码可用两个字符表示,这两个字符可以添加在指令助记符的后面和指令同时使用。例如,跳转指令B可以加上后

缀EQ变为BEQ表示“相等则跳转”,即当CPSR中的Z标志置位时发生跳转2022/12/5嵌入式系统原理及应用刘军芳7NZCV——IM0M1M2M3M4TF—...313029282726876543210

程序状态寄存器条件代码标志保留控制位溢出标志oVerflow进位或借位扩展Carry零Zero负或小于NegativeIRQ禁止InterruptFIQ禁止Fast状态位Thumb模式位ModeNZCVIM0M1M2M3M4

TFCPSR寄存器的格式2022/12/5嵌入式系统原理及应用刘军芳8指令的条件码在16种条件标志码中,只有15种可以使用,第16种(1111)为系统保留,暂时不能使用。2022/12/5嵌入式系统原理及应用刘军芳9S

后缀指令中使用S后缀时,指令执行后程序状态寄存器的条件标志位将被刷新,不使用S后缀时,指令执行后程序状态寄存器的条件标志将不会发生变化。S后缀通常用于对条件进行测试,例如是否有溢出,是否进位等;根据这些变化,就可以进行一些判断,如是否大于,是

否相等;从而可能影响指令执行的顺序。2022/12/5嵌入式系统原理及应用刘军芳10条件后缀和S后缀的关系如下:(1)如果既有条件后缀又有S后缀,则书写时S排在后面,如:ADDEQSR1,R0,R2该

指令在Z=1时执行,将R0+R2的值放入R1,同时刷新条件标志位。(2)条件后缀是要测试条件标志位,而S后缀是要刷新条件标志位。(3)条件后缀要测试的是执行前的标志位,而S后缀是依据指令的结果改变条件标志。2022/

12/5嵌入式系统原理及应用刘军芳11例:假设R0=0x1,R3=0x3,指令执行之前CPSR=nzcvqIFt_SVC,分别执行如下指令CPSR的值有何变化?SUBR1,R0,R3;R0的值减去R3的

值,结果存入R1SUBSR1,R0,R3;R0的值减去R3的值,结果存入R1影响标志位分析:执行第1条指令对于标志寄存器的值没有任何影响,因此CPSR的值不变。执行第2条指令后CPSR=NzcvqIFt_SVC,因为R0的值减去R3值,结果

变成负数,故而N被置位了2022/12/5嵌入式系统原理及应用刘军芳124.1.3ARM指令中的操作数符号ARM指令格式中的操作数有不同的符号,说明如下:1、立即数符号##符号表示一个立即数,该符号后的数据可以是十进制、二进制或十六进制数。#22、二进制

符号%(2)%后面的数字表示二进制数,例如:%10010101(210010101),表示二进制数10010101,即十进制数149。3、十六进制数0x0x后面的数字表示十六进制数,如:0xFFFF,表示十六进制数FFFF,即十进制数的6553520

22/12/5嵌入式系统原理及应用刘军芳13ARM指令中的操作数符号(续1)5、更新基地址寄存器符号!!符号表示指令在完成操作后应将最后的地址写入基址寄存器。如果指令地址表达式中不含!后缀,则基址寄存器中的地址值不会发生变化。指令中的地址表达式中

含有!后缀时,指令执行后,基址寄存器中的地址值将发生变化,变化的结果如下:基址寄存器中的值(指令执行后)=指令执行前的值+地址偏移量2022/12/5嵌入式系统原理及应用刘军芳14例分别执行下面两条指令有何区别?LDRR3,[R0,#4]LDRR3,[R0,#4]!分析:在上述指令

中,第1条指令没有后缀!,指令的结果是把R0加4作为地址指针,把这个指针所指向的地址单元所存储的数据读入R3,R0的值不变。第2条指令除了实现以上操作外,还把R0+4的结果送到R0中。2022/12/5嵌入式系统原

理及应用刘军芳15使用!后缀需要注意如下事项:(1)!后缀必须紧跟在地址表达式后面,而地址表达式要有明确的地址偏移量。(2)!后缀不能用于R15(PC)的后面2022/12/5嵌入式系统原理及应用刘军芳166、复制SPSR到CPSR符号ˆˆ该符号通常在批量数据存储指令中作为后缀放

在存储器之后,当前寄存器不包含PC时,该符号表示所用的寄存器使用户模式的寄存器;当其前面的寄存器包含PC时,该符号指示将SPSR寄存器的值复制到CPSR寄存器中。7、指示寄存器列表范围符号——符号用于有些指令中表示多个连续的寄存器时,及从…到…。例如:R0—R7,表示R0、R1….R7,8个寄

存器。2022/12/5嵌入式系统原理及应用刘军芳174.1.4ARM指令中的移位操作ARM微处理器内嵌的桶型移位器(BarrelShifter),支持数据的各种移位操作,移位操作在ARM指令集中不作为单独的指令使用,它只能作为指令格式中是一个字

段,在汇编语言中表示为指令中的选项。例如,数据处理指令的第二个操作数为寄存器时,就可以加入移位操作选项对它进行各种移位操作。移位操作包括如下6种类型,LSL逻辑左移、ASL算术左移、LSR逻辑右移、ASR算术右移、ROR循环右移、RRX带扩展的循环右移;ASL

和LSL是等价的,可以自由互换:2022/12/5嵌入式系统原理及应用刘军芳184.2指令集介绍桶形移位器支持数据的各种移位操作ALU桶形移位器Rd结果N预处理未预处理RmRn2022/12/5嵌入式系统原理及应用刘军芳19ARM指令中的移位操作(续1)

1、LSL(或ASL)逻辑(或算术)左移操作LSL(或ASL)操作的格式为:通用寄存器,LSL(或ASL)操作数用途:LSL(或ASL)可完成对通用寄存器中的内容进行逻辑(或算术)的左移操作,按操作数所指定的数量向左移位,低位用零来填充。其中,操作数可以用一个立即值

(从0到31)指定移位数量,或用包含在0和31之间的一个值的寄存器指定移位数量。操作示例:MOVR0,R1,LSL#2;将R1中的内容左移两位后传送到R0中。2022/12/5嵌入式系统原理及应用刘军芳20ARM指令中的移位操作(续2)2、LSR逻辑右移

操作LSR操作的格式为:通用寄存器,LSR操作数用途:LSR可完成对通用寄存器中的内容进行右移的操作,按操作数所指定的数量向右移位,左端用零来填充。其中,操作数操作数可以用一个立即值(从0到31)指定移位数量,或用包

含在0和31之间的一个值的寄存器指定移位数量。操作示例:MOVR0,R1,LSR#2;将R1中的内容右移两位后传送到;R0中,左端用零来填充。2022/12/5嵌入式系统原理及应用刘军芳21ARM指令中的移位操作(续3)3、ASR算数右移操作ASR操作的格式为

:通用寄存器,ASR操作数用途:ASR可完成对通用寄存器中的内容进行算数右移的操作,按操作数所指定的数量向右移位,左端用第31位的值来填充。其中,操作数操作数可以用一个立即值(从0到31)指定移位数量,或用包含在0和31之间的一个值的寄存器指定移位数量。

操作示例:MOVR0,R1,ASR#2;将R1中的内容右移两位后传送到R0中,左端用第31位的值来填充。2022/12/5嵌入式系统原理及应用刘军芳22ARM指令中的移位操作(续4)4、ROR循环右移操作ROR操作的格式为:通用寄存器,ROR操作数用途:ROR可完成对通用寄

存器中的内容进行循环右移的操作,按操作数所指定的数量向右循环移位,左端用右端移出的位来填充。其中,操作数可以是通用寄存器,也可以是立即数(0~31)。显然,当进行32位的循环右移操作时,通用寄存器中的值不改变。操作示例:MOVR0,R1,ROR#2;将R1中的内容循环右移两位后传送到R

0中。2022/12/5嵌入式系统原理及应用刘军芳23ARM指令中的移位操作(续5)5、RRX带扩展的循环右移操作RRX操作的格式为:通用寄存器,RRX操作数用途:RRX可完成对通用寄存器中的内容进行带扩展的循环右移的操作,按操

作数所指定的数量向右循环移位,左端用进位标志位C来填充。其中,操作数可以是通用寄存器,也可以是立即数(0~31)。操作示例:MOVR0,R1,RRX#2;将R1中的内容进行带扩展的循环右移两位后传送到R0中。2022/12/5嵌入式系统原理

及应用刘军芳244.2ARM处理器寻址方式寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式。ARM处理器具有7种基本寻址方式。1.立即寻址;2.寄存器寻址;3.寄存器间接寻址;4.基址加

变址寻址;5.相对寻址;6.堆栈寻址;7.多寄存器寻址;2022/12/5嵌入式系统原理及应用刘军芳25寻址方式分类——立即寻址立即寻址指令中的操作码字段后面的地址码部分即是操作数本身,也就是说,数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(这样的数称为立即数)。立即寻

址指令举例如下:SUBSR0,R0,#1;R0减1,结果放入R0,并且影响标志位MOVR0,#0xFF000;将立即数0xFF000装入R0寄存器0x55R0MOVR0,#0xFF00程序存储MOVR0,#0xFF000xFF00从代码中获得数据2022/12/5嵌入式系统原理及应用

刘军芳26寻址方式分类——寄存器寻址操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值来操作。寄存器寻址指令举例如下:MOVR1,R2;将R2的值存入R1SUBR0,R1,R2;将R1的值减去R2的值,结果保存到R00xAA0x55R2R1MOVR1,R

20xAA2022/12/5嵌入式系统原理及应用刘军芳27寄存器间接寻址指令中的地址码给出的是一个通用寄存器的编号,所需的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针。寄存器间接寻址指令举例如下:LDRR1,[R2];将R2指向的存储单元的数据读出,保存在R1中

SWPR1,R1,[R2];将寄存器R1的值和R2指定的存储单元的内容交换0x55R0R20x400000000xAA0x40000000寻址方式分类——寄存器间接寻址LDRR0,[R2]0xAA2022/12/5嵌入式系统原理及应用刘军芳28基址寻址就是将

基址寄存器的内容与指令中给出的偏移量(<4K)相加/减,形成操作数的有效地址。基址寻址用于访问基址附近的存储单元,常用于查表、数组操作、功能部件寄存器访问等。寄存器间接寻址是偏移量为0的基址加偏移寻址。

基址寻址指令举例如下(前索引寻址):LDRR2,[R3,#0x0C];读取R3+0x0C地址上的存储单元;的内容,放入R2STRR1,[R0,#-4]!;先R0=R0-4,然后把R0的值寄存;到保存到R1指定的存储单元寻址方式分类——基址(加变址)寻址0x

55R2R30x400000000xAA0x4000000CLDRR2,[R3,#0x0C]0xAA将R3+0x0C作为地址装载数据2022/12/5嵌入式系统原理及应用刘军芳29寻址方式分类——基址(加变址)寻址基址寻址指令举例如下:

LDRR0,[R1],#4;R0=[R1],R1=R1+4;后索引基址寻址;ARM这种自动索引机制不消耗;额外的时间LDRR0,[R1,R2];R0=[R1+R2]2022/12/5嵌入式系统原理及应用刘军芳30相对寻址是基址寻址的一种变通。由程序计数器P

C提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。相对寻址指令举例如下:BLSUBR1;调用到SUBR1子程序BEQLOOP;条件跳转到LOOP标号处...LOOPMOVR6,#1...SUB

R1...寻址方式分类——相对寻址2022/12/5嵌入式系统原理及应用刘军芳31堆栈是一个按特定顺序进行存取的存储区,操作顺序为“后进先出”。堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(

堆栈),指针所指向的存储单元即是堆栈的栈顶。存储器堆栈可分为两种:向上生长:向高地址方向生长,称为递增堆栈向下生长:向低地址方向生长,称为递减堆栈ARM中采用LDMFD和STMFD指令分别用来支持POP操作(出栈)和PUSH操作(进栈),R13作为堆栈指

针。寻址方式分类——堆栈寻址2022/12/5嵌入式系统原理及应用刘军芳32寻址方式分类——堆栈寻址(续1)栈底栈顶栈区SP堆栈存储区栈顶栈底栈区SP向下增长向上增长0x123456780x12345678堆栈压栈堆栈

压栈2022/12/5嵌入式系统原理及应用刘军芳33栈顶SP栈顶SP栈底空堆栈栈底满堆栈堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个待压入数据的空位置,称为空堆栈。寻址方式分类——堆栈寻址(续2)0x12

3456780x12345678栈顶SP0x12345678栈顶SP压栈压栈2022/12/5嵌入式系统原理及应用刘军芳34所以可以组合出四种类型的堆栈方式:满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。指令如LDMFA、STMFA等;空递增:堆栈向上增长,堆栈指针指向堆栈

上的第一个空位置。指令如LDMEA、STMEA等;满递减:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。指令如LDMFD、STMFD等;空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。指令如LDMED、STMED等。寻址方式分类——堆栈寻址(续3)2

022/12/5嵌入式系统原理及应用刘军芳35多寄存器寻址一次可传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器。多寄存器寻址指令举例如下:LDMIAR1!,{R2-R7,R12};将R1指向的单元中的数据读出到;R2~R7、R12中(R1自动加4)STMIAR0!,{R2-

R7,R12};将寄存器R2~R7、R12的值保;存到R0指向的存储单元中;(R0自动加4)0x40000000R1R20x??0x010x400000000x??R3R40x??R60x??0x02

0x030x040x400000040x400000080x4000000C存储器寻址方式分类——多寄存器寻址LDRR1!,{R2-R4,R6}0x010x020x030x040x400000102022/12/5嵌入式系统原理及应用刘军芳364.3ARM指令集数据处理指令大致可分为3类:数

据传送指令;算术逻辑运算指令;比较指令。数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。所有ARM数据处理指令均可选择使用S后缀,以使指令影响状态标志。2022/12/5嵌入式系统原理及应用刘军芳374.3.1数据处理指令数据处理指令

包括:—MOV数据传送指令—MVN数据取反传送指令—CMP比较指令—CMN反值比较指令—TST位测试指令—TEQ相等测试指令—ADD加法指令—ADC带进位加法指令—SUB减法指令—SBC带借位减法指令—RSB逆向减法指令—RSC带借位的逆向减法指令—AND逻辑与指令—O

RR逻辑或指令—EOR逻辑异或指令—BIC位清除指令2022/12/5嵌入式系统原理及应用刘军芳38ARM数据处理指令——指令编码指令执行的条件码I用于区别立即数(I为1)和寄存器移位(I为0)opcode数据处理指令操作码第二操作数Rd目标寄存器Rn第一操

作数寄存器S设置条件码,与指令中的S位对应带进位加法ADC0101带进位减法指令SBC0110带进位逆向减法指令RSC0111位测试指令TST1000相等测试指令TEQ1001比较指令CMP1010负数比较指令CMN1011逻辑或操作指

令ORR1100数据传送MOV1101位清除指令BIC1110数据非传送MVN1111加法运算指令ADD0100逆向减法指令RSB0011减法运算指令SUB0010逻辑异或操作指令EOR0001逻辑与操作指

令AND0000说明指令助记符操作码opcode操作码功能表2022/12/5嵌入式系统原理及应用刘军芳39助记符说明操作条件码位置MOVRd,operand2数据传送Rd←operand2MOV{cond}{S}MVNRd,

operand2数据非传送Rd←(~operand2)MVN{cond}{S}ARM数据处理指令——数据传送注:当后缀S时,这些指令根据结果更新标志N和Z,在计算Operand2时更新标志C,不影响标志V。2022/12/5

嵌入式系统原理及应用刘军芳40助记符说明操作条件码位置MOVRd,operand2数据传送Rd←operand2MOV{cond}{S}MVNRd,operand2数据非传送Rd←(~operand2)MVN{cond}{S}ARM数据处理指令——数据传送MOV指令将立

即数或寄存器传送到目标寄存器(Rd),可用于移位运算等操作。指令格式如下:MOV{cond}{S}Rd,operand2MOV指令举例如下:MOVR1,#0xF000000B;R1=0xF000000BMOV

R0,R1;R0=R1MOVSR3,R1,LSL#2;R3=R1<<2,并影响标志位MOVPC,LR;PC=LR,子程序返回2022/12/5嵌入式系统原理及应用刘军芳41助记符说明操作条件码位置MOVRd,operand2数据传送Rd←operand2MOV{cond}{S}MVNRd,ope

rand2数据非传送Rd←(~operand2)MVN{cond}{S}ARM数据处理指令——数据传送MVN指令将立即数或寄存器(operand2)按位取反后传送到目标寄存器,因为其具有取反功能,所以可以装载范围更广的立即数。指令格式如下:MVN{cond}{S}

Rd,operand2MVN指令举例如下:MVNR1,#0xFF;R1=0xFFFFFF00MVNR1,R2;将R2按位取反,结果存到R12022/12/5嵌入式系统原理及应用刘军芳42助记符说明操作条件码位置CMPRn,operand2比较指令标志N、Z、C、V←Rn-operand2CM

P{cond}CMNRn,operand2负数比较指令标志N、Z、C、V←Rn+operand2CMN{cond}TSTRn,operand2位测试指令标志N、Z、C、V←Rn&operand2TST{cond}TEQRn,operand2相等测试指令标志N、Z、C、V←Rn^operand2TE

Q{cond}ARM数据处理指令——比较指令注:这些指令直接影响N,Z,C和V标志位。2022/12/5嵌入式系统原理及应用刘军芳43助记符说明操作条件码位置CMPRn,operand2比较指令标志N、Z、C

、V←Rn-operand2CMP{cond}CMNRn,operand2负数比较指令标志N、Z、C、V←Rn+operand2CMN{cond}TSTRn,operand2位测试指令标志N、Z、C、V←Rn&operand2TST{cond

}TEQRn,operand2相等测试指令标志N、Z、C、V←Rn^operand2TEQ{cond}ARM数据处理指令——比较指令比较指令——CMP指令将寄存器Rn的值减去operand2的值,根据操

作的结果更新CPSR中的相应条件标志位(N/Z/C/V),以便后面的指令根据相应的条件标志来判断是否执行。CMP指令与SUBS指令的区别在于CMP指令不保存运算结果。指令格式如下:CMP{cond}Rn,operand2应用示例:CMPR1,#10

;R1与10比较,设置相关标志位CMPGTR1,R2;R1与R2比较,设置相关标志位;若R1>10,则执行本指令2022/12/5嵌入式系统原理及应用刘军芳44助记符说明操作条件码位置CMPRn,operand2比较指令标志N、

Z、C、V←Rn-operand2CMP{cond}CMNRn,operand2负数比较指令标志N、Z、C、V←Rn+operand2CMN{cond}TSTRn,operand2位测试指令标志N、Z、C、V←Rn&operand2TST{

cond}TEQRn,operand2相等测试指令标志N、Z、C、V←Rn^operand2TEQ{cond}ARM数据处理指令——比较指令负数比较指令——CMN指令用于把一个寄存器的内容和另一个寄存器的内容或立即数取反后进行比较,同时更新CPSR中条件标志位的值。该指令实际完成操

作数1和操作数2相加,并根据结果更改条件标志位:CMN{cond}Rn,operand2应用示例:CMNR0,#1;R0+12022/12/5嵌入式系统原理及应用刘军芳45助记符说明操作条件码位置CMPRn,operand2比较指令标志N、Z、C、V←Rn-operand2CMP{cond}C

MNRn,operand2负数比较指令标志N、Z、C、V←Rn+operand2CMN{cond}TSTRn,operand2位测试指令标志N、Z、C、V←Rn&operand2TST{cond}TEQRn,operand2相等测试指令标志N、Z、C、V←Rn^operand2T

EQ{cond}ARM数据处理指令——比较指令位测试指令——TST指令将寄存器Rn的值与operand2的值按位作逻辑“与”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。指令格式如下:TST{cond}Rn,operand2应用示例:

TSTR0,#0x01;判断R0的最低位是否为0TSTR1,#0x0F;判断R1的低4位是否为02022/12/5嵌入式系统原理及应用刘军芳46助记符说明操作条件码位置CMPRn,operand2比较指令标志N、Z、C、V←Rn-operand2C

MP{cond}CMNRn,operand2负数比较指令标志N、Z、C、V←Rn+operand2CMN{cond}TSTRn,operand2位测试指令标志N、Z、C、V←Rn&operand2TST{cond}TEQRn,operand2相等测试指令标志N、Z、C

、V←Rn^operand2TEQ{cond}ARM数据处理指令——比较指令相等测试指令——TEQ指令将寄存器Rn的值与operand2的值按位作逻辑“异或”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后

面的指令根据相应的条件标志来判断是否执行。指令格式如下:TEQ{cond}Rn,operand2应用示例:TEQR0,R1;比较R0与R1是否相等2022/12/5嵌入式系统原理及应用刘军芳47助记符说明操作条件

码位置ADDRd,Rn,operand2加法运算指令Rd←Rn+operand2ADD{cond}{S}SUBRd,Rn,operand2减法运算指令Rd←Rn-operand2SUB{cond}{S}RSB

Rd,Rn,operand2逆向减法指令Rd←operand2-RnRSB{cond}{S}ADCRd,Rn,operand2带进位加法Rd←Rn+operand2+CarryADC{cond}{S}SBCRd,Rn,operand2带进位减法指令Rd←Rn

-operand2-(NOT)CarrySBC{cond}{S}RSCRd,Rn,operand2带进位逆向减法指令Rd←operand2-Rn-(NOT)CarryRSC{cond}{S}ARM数据处

理指令——算术运算注:这些指令不直接影响N,Z,C和V标志位,如果要影响标志位,则需要加S。2022/12/5嵌入式系统原理及应用刘军芳48助记符说明操作条件码位置ADDRd,Rn,operand2加法运算指令Rd←Rn+operand2ADD{cond}{S}SUBRd,Rn,oper

and2减法运算指令Rd←Rn-operand2SUB{cond}{S}RSBRd,Rn,operand2逆向减法指令Rd←operand2-RnRSB{cond}{S}ADCRd,Rn,operand2带进位加法Rd←Rn+operand2+

CarryADC{cond}{S}SBCRd,Rn,operand2带进位减法指令Rd←Rn-operand2-(NOT)CarrySBC{cond}{S}RSCRd,Rn,operand2带进位逆向减法

指令Rd←operand2-Rn-(NOT)CarryRSC{cond}{S}ARM数据处理指令——算术运算加法运算指令——ADD指令将operand2的值与Rn的值相加,结果保存到Rd寄存器。指令格式如下:ADD{cond}{S}

Rd,Rn,operand2应用示例:ADDSR1,R1,#1020;R1=R1+1020,并影响标志位ADDR1,R1,R2,LSL#2;R1=R1+R2<<22022/12/5嵌入式系统原理及应用刘军芳49助记符说明操作条件码位置AD

DRd,Rn,operand2加法运算指令Rd←Rn+operand2ADD{cond}{S}SUBRd,Rn,operand2减法运算指令Rd←Rn-operand2SUB{cond}{S}RSBRd,Rn,

operand2逆向减法指令Rd←operand2-RnRSB{cond}{S}ADCRd,Rn,operand2带进位加法Rd←Rn+operand2+CarryADC{cond}{S}SBCRd,Rn,operand2带进位减法指令Rd←Rn-operand

2-(NOT)CarrySBC{cond}{S}RSCRd,Rn,operand2带进位逆向减法指令Rd←operand2-Rn-(NOT)CarryRSC{cond}{S}ARM数据处理指令——算术运算减法运算指令——SUB指令用寄存器Rn减去operand2,结果

保存到Rd中。指令格式如下:SUB{cond}{S}Rd,Rn,operand2应用示例:SUBSR0,R0,#240;R0=R0-240,并影响标志位SUBSR2,R1,R2;R2=R1-R2,并影响标志位2022/12/5嵌入式系统原理及应用刘军

芳50助记符说明操作条件码位置ADDRd,Rn,operand2加法运算指令Rd←Rn+operand2ADD{cond}{S}SUBRd,Rn,operand2减法运算指令Rd←Rn-operand2SUB{cond}{S}RSBRd,Rn,op

erand2逆向减法指令Rd←operand2-RnRSB{cond}{S}ADCRd,Rn,operand2带进位加法Rd←Rn+operand2+CarryADC{cond}{S}SBCRd,Rn,operand2带进位减法指令Rd←Rn-operand2-(NOT)Car

rySBC{cond}{S}RSCRd,Rn,operand2带进位逆向减法指令Rd←operand2-Rn-(NOT)CarryRSC{cond}{S}ARM数据处理指令——算术运算逆向减法运算指令——RSB指令将operand2的值减去Rn,结果保存到Rd中。指令格式如下:RSB{c

ond}{S}Rd,Rn,operand2应用示例:RSBR3,R1,#0xFF00;R3=0xFF00-R1RSBSR1,R2,R2,LSL#2;R1=(R2<<2)-R2=R2×3影响标志位2022/12/5嵌入式系统原理及应用刘军芳51助记符说明操作条件

码位置ADDRd,Rn,operand2加法运算指令Rd←Rn+operand2ADD{cond}{S}SUBRd,Rn,operand2减法运算指令Rd←Rn-operand2SUB{cond}{S}RSBRd,Rn,operand2

逆向减法指令Rd←operand2-RnRSB{cond}{S}ADCRd,Rn,operand2带进位加法Rd←Rn+operand2+CarryADC{cond}{S}SBCRd,Rn,operand2带进位减法指令Rd←Rn-operand2-(NOT)CarrySBC{cond

}{S}RSCRd,Rn,operand2带进位逆向减法指令Rd←operand2-Rn-(NOT)CarryRSC{cond}{S}ARM数据处理指令——算术运算带进位加法指令——ADC将operand2的值与Rn的值相

加,再加上CPSR中的C条件标志位,结果保存到Rd寄存器。指令格式如下:ADC{cond}{S}Rd,Rn,operand2应用示例(使用ADC实现64位加法,结果存于R1(高32位)、R0中):ADDSR0,R0,R2;R0等于低32位相加

,并影响标志位ADCR1,R1,R3;R1等于高32位相加,并加上低位进位2022/12/5嵌入式系统原理及应用刘军芳52助记符说明操作条件码位置ADDRd,Rn,operand2加法运算指令Rd←Rn+operand2ADD{cond}{S}SU

BRd,Rn,operand2减法运算指令Rd←Rn-operand2SUB{cond}{S}RSBRd,Rn,operand2逆向减法指令Rd←operand2-RnRSB{cond}{S}ADCR

d,Rn,operand2带进位加法Rd←Rn+operand2+CarryADC{cond}{S}SBCRd,Rn,operand2带进位减法指令Rd←Rn-operand2-(NOT)CarrySBC{cond}{S}RSCRd,Rn,ope

rand2带进位逆向减法指令Rd←operand2-Rn-(NOT)CarryRSC{cond}{S}ARM数据处理指令——算术运算带进位减法指令——SBC用寄存器Rn减去operand2,再减去CPSR中的

C条件标志位的非(即若C标志清零,则结果减去1),结果保存到Rd中。指令格式如下:SBC{cond}{S}Rd,Rn,operand2应用示例(使用SBC实现64位减法,结果存于R1、R0中):SUBSR0,R0,R2;低32位相减,并影响标志位SBCR1,R1,R3;高32位相减,并减去低位

借位2022/12/5嵌入式系统原理及应用刘军芳53助记符说明操作条件码位置ADDRd,Rn,operand2加法运算指令Rd←Rn+operand2ADD{cond}{S}SUBRd,Rn,operan

d2减法运算指令Rd←Rn-operand2SUB{cond}{S}RSBRd,Rn,operand2逆向减法指令Rd←operand2-RnRSB{cond}{S}ADCRd,Rn,operand2带进位加法Rd←Rn+operand2+CarryADC{con

d}{S}SBCRd,Rn,operand2带进位减法指令Rd←Rn-operand2-(NOT)CarrySBC{cond}{S}RSCRd,Rn,operand2带进位逆向减法指令Rd←opera

nd2-Rn-(NOT)CarryRSC{cond}{S}ARM数据处理指令——算术运算带进位逆向减法指令——RSC指令用寄存器operand2减去Rn,再减去CPSR中的C条件标志位,结果保存到Rd中。指令格式如下:RSC{cond}{S}Rd,Rn,o

perand2应用示例(使用RSC指令实现求64位数值的负数):RSBSR2,R0,#0;R2=-R0RSCR3,R1,#0;R3=-R1-!Carry2022/12/5嵌入式系统原理及应用刘军芳54助记符说明

操作条件码位置ANDRd,Rn,operand2逻辑与操作指令Rd←Rn&operand2AND{cond}{S}ORRRd,Rn,operand2逻辑或操作指令Rd←Rn|operand2ORR{cond}{S}EORRd,Rn,operand2逻辑异或操作指令Rd

←Rn^operand2EOR{cond}{S}BICRd,Rn,operand2位清除指令Rd←Rn&(~operand2)BIC{cond}{S}ARM数据处理指令——逻辑运算指令注:当后缀S时,这些指令根据结果更新标志N和Z,在计算Operand2时更新标志C,不影响标志

V。2022/12/5嵌入式系统原理及应用刘军芳55助记符说明操作条件码位置ANDRd,Rn,operand2逻辑与操作指令Rd←Rn&operand2AND{cond}{S}ORRRd,Rn,operand2逻辑或操作指令Rd←Rn|operand2ORR{c

ond}{S}EORRd,Rn,operand2逻辑异或操作指令Rd←Rn^operand2EOR{cond}{S}BICRd,Rn,operand2位清除指令Rd←Rn&(~operand2)BIC{cond}{S}ARM数据处理指令——逻辑运算指令逻辑与

操作指令——AND指令将operand2的值与寄存器Rn的值按位作逻辑“与”操作,结果保存到Rd中。指令格式如下:AND{cond}{S}Rd,Rn,operand2应用示例:ANDSR0,R0,#0x01;R0=R0&0x01,取出最低位数据ANDEQR2,R

1,R3;R2=R1&R32022/12/5嵌入式系统原理及应用刘军芳56助记符说明操作条件码位置ANDRd,Rn,operand2逻辑与操作指令Rd←Rn&operand2AND{cond}{S}OR

RRd,Rn,operand2逻辑或操作指令Rd←Rn|operand2ORR{cond}{S}EORRd,Rn,operand2逻辑异或操作指令Rd←Rn^operand2EOR{cond}{S}BICRd,Rn,opera

nd2位清除指令Rd←Rn&(~operand2)BIC{cond}{S}ARM数据处理指令——逻辑运算指令逻辑或操作指令——ORR指令将operand2的值与寄存器Rn的值按位作逻辑“或”操作,结果保存到Rd中。指令格式如下:ORR{cond}{S}Rd

,Rn,operand2应用示例:ORRR0,R0,#0x0F;将R0的低4位置1MOVR1,R2,LSR#24;使用ORR指令将R2的高8位ORRR3,R1,R3,LSL#8;数据移入到R3低8位中2022/12/5嵌入式系统原理及应用刘军芳57助记符说明操作条

件码位置ANDRd,Rn,operand2逻辑与操作指令Rd←Rn&operand2AND{cond}{S}ORRRd,Rn,operand2逻辑或操作指令Rd←Rn|operand2ORR{cond}{S}EORRd,Rn,operand2逻辑异或操作指令Rd←Rn^oper

and2EOR{cond}{S}BICRd,Rn,operand2位清除指令Rd←Rn&(~operand2)BIC{cond}{S}ARM数据处理指令——逻辑运算指令逻辑异或操作指令——EOR指令将operand2的值与寄存器Rn的值按位作逻辑“异或”操作,结果保存

到Rd中。指令格式如下:EOR{cond}{S}Rd,Rn,operand2应用示例:EORR1,R1,#0x0F;将R1的低4位取反EORR2,R1,R0;R2=R1^R0EORSR0,R5,#0x01;将R5和0x01进行逻辑异或,;结果保存到R0,并影响标志

位2022/12/5嵌入式系统原理及应用刘军芳58助记符说明操作条件码位置ANDRd,Rn,operand2逻辑与操作指令Rd←Rn&operand2AND{cond}{S}ORRRd,Rn,operand2

逻辑或操作指令Rd←Rn|operand2ORR{cond}{S}EORRd,Rn,operand2逻辑异或操作指令Rd←Rn^operand2EOR{cond}{S}BICRd,Rn,operand2位

清除指令Rd←Rn&(~operand2)BIC{cond}{S}ARM数据处理指令——逻辑运算指令位清除指令——BIC指令将寄存器Rn的值与operand2的值的反码按位作逻辑“与”操作,结果保存到Rd中。指令格式如下:BIC{cond}{S}Rd,R

n,operand2应用示例:BICR1,R1,#0x0F;将R1的低4位清零,其它位不变BICR1,R2,R3;将R3的反码和R2相逻辑“与”,;结果保存到R1中2022/12/5嵌入式系统原理及应用刘军芳59ARM指令

集——乘法指令ARM7TDMI具有三种乘法指令,分别为:32×32位乘法指令;32×32位乘加指令;32×32位结果为64位的乘/乘加指令。2022/12/5嵌入式系统原理及应用刘军芳60ARM指令——乘法指

令•乘法指令编码指令执行的条件码Opcode乘法指令操作码S设置条件码,与指令中的S位对应Rm为被乘数寄存器Rn/RdLo为MLA指令相加的寄存器或64位乘法指令的目标寄存器(低32位)Rd/RdHi为目标寄存器或64位乘法指令的目标寄存器(高32位)Rs为乘数寄存

器64位有符号乘加指令SMLAL11164位有符号乘法指令SMULL11064位无符号乘加指令UMLAL10164位无符号乘法指令UMULL10032位乘加指令MLA00132位乘法指令MUL000说明指令助记符操作码

opcode操作码功能表2022/12/5嵌入式系统原理及应用刘军芳61助记符说明操作条件码位置MULRd,Rm,Rs32位乘法指令Rd←Rm*Rs(Rd≠Rm)MUL{cond}{S}MLARd,Rm,Rs,Rn32位乘加指令Rd←Rm*Rs+Rn(Rd≠Rm)MLA{con

d}{S}UMULLRdLo,RdHi,Rm,Rs64位无符号乘法指令(RdLo,RdHi)←Rm*RsUMULL{cond}{S}UMLALRdLo,RdHi,Rm,Rs64位无符号乘加指令(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)UM

LAL{cond}{S}SMULLRdLo,RdHi,Rm,Rs64位有符号乘法指令(RdLo,RdHi)←Rm*RsSMULL{cond}{S}SMLALRdLo,RdHi,Rm,Rs64位有符号乘加指令(RdLo,R

dHi)←Rm*Rs+(RdLo,RdHi)SMLAL{cond}{S}ARM指令——乘法指令2022/12/5嵌入式系统原理及应用刘军芳62助记符说明操作条件码位置MULRd,Rm,Rs32位乘法指令Rd←Rm*Rs(Rd≠Rm)MUL{cond}{S}MLARd,Rm,Rs,Rn32位乘加

指令Rd←Rm*Rs+Rn(Rd≠Rm)MLA{cond}{S}UMULLRdLo,RdHi,Rm,Rs64位无符号乘法指令(RdLo,RdHi)←Rm*RsUMULL{cond}{S}UMLALRdLo,RdHi,Rm,Rs64位无符号乘加指令(RdLo,RdHi)←Rm*Rs+

(RdLo,RdHi)UMLAL{cond}{S}SMULLRdLo,RdHi,Rm,Rs64位有符号乘法指令(RdLo,RdHi)←Rm*RsSMULL{cond}{S}SMLALRdLo,RdHi,Rm,

Rs64位有符号乘加指令(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)SMLAL{cond}{S}ARM指令——乘法指令32位乘法指令——MUL指令将Rm和Rs中的值相乘,结果的低32位保存到Rd中

。Rd,Rm,Rs不能为R15。S选项决定指令的操作是否影响CPSR中条件标志位的值,有S时指令执行后的结果影响CPSR中条件标志位N和Z值,在ARMv4及以前版本中,标志C和V不可靠,在ARMV5及以后版本中不

影响C和V标志。指令格式如下:2022/12/5嵌入式系统原理及应用刘军芳63MUL{cond}{S}Rd,Rm,Rs应用示例:MULR1,R2,R3;R1=R2×R3MULSR0,R3,R7;R0=R3×R7,影

响CPSR中的N位和Z位2022/12/5嵌入式系统原理及应用刘军芳64助记符说明操作条件码位置MULRd,Rm,Rs32位乘法指令Rd←Rm*Rs(Rd≠Rm)MUL{cond}{S}MLARd,Rm,Rs,Rn32位乘加指令Rd←Rm*Rs+Rn(Rd≠Rm)

MLA{cond}{S}UMULLRdLo,RdHi,Rm,Rs64位无符号乘法指令(RdLo,RdHi)←Rm*RsUMULL{cond}{S}UMLALRdLo,RdHi,Rm,Rs64位无符号乘加指令(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)UMLAL{cond}{S}SMU

LLRdLo,RdHi,Rm,Rs64位有符号乘法指令(RdLo,RdHi)←Rm*RsSMULL{cond}{S}SMLALRdLo,RdHi,Rm,Rs64位有符号乘加指令(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)SMLAL{cond}{S}ARM

指令——乘法指令32位乘加指令——MLA指令将Rm和Rs中的值相乘,再将乘积加上第3个操作数,结果的低32位保存到Rd中。Rd,Rm,Rs,Rn不能为R15。S只影响CPSR中的N位和Z位,不影响V,C不确定。指令格式如下:MLA{cond}{S}Rd,Rm,R

s,Rn应用示例:MLAR1,R2,R3,R0;R1=R2×R3+R02022/12/5嵌入式系统原理及应用刘军芳65助记符说明操作条件码位置MULRd,Rm,Rs32位乘法指令Rd←Rm*Rs(Rd≠Rm)MUL{cond}{S}MLARd,Rm,Rs,Rn32位

乘加指令Rd←Rm*Rs+Rn(Rd≠Rm)MLA{cond}{S}UMULLRdLo,RdHi,Rm,Rs64位无符号乘法指令(RdLo,RdHi)←Rm*RsUMULL{cond}{S}UMLALRdLo,RdHi,Rm,Rs6

4位无符号乘加指令(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)UMLAL{cond}{S}SMULLRdLo,RdHi,Rm,Rs64位有符号乘法指令(RdLo,RdHi)←Rm*RsSMULL

{cond}{S}SMLALRdLo,RdHi,Rm,Rs64位有符号乘加指令(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)SMLAL{cond}{S}ARM指令——乘法指令64位无符号乘法指令——UMULL指令

将Rm和Rs中的值作无符号数相乘,结果的低32位保存到RdLo中,而高32位保存到RdHi中。RdLo/Hi,Rm,Rs不能为R15。RdLo/Hi,Rm必须是不同的寄存器。S只影响CPSR中的N位和Z位,标志C和V不确

定。指令格式如下:UMULL{cond}{S}RdLo,RdHi,Rm,Rs应用示例:UMULLR0,R1,R5,R8;(R1、R0)=R5×R82022/12/5嵌入式系统原理及应用刘军芳6664位乘法又称为长整型乘法指令,由于结果太大,不能在放在一个32位的寄存器中,所以把结

果存放在2个32位的寄存器Rdlo和Rdhi中。Rdlo存放低32位,Rdhi存放高32位。与前面的数据处理指令不同,指令中的所有源操作数、目的寄存器必须为通用寄存器,不能对操作数使用立即数或被移位的寄存器。同时,目的寄存器Rd和操作数Rm必

须是不同的寄存器。2022/12/5嵌入式系统原理及应用刘军芳67助记符说明操作条件码位置MULRd,Rm,Rs32位乘法指令Rd←Rm*Rs(Rd≠Rm)MUL{cond}{S}MLARd,Rm,Rs,Rn32位乘加指令Rd←Rm*Rs+Rn(Rd≠Rm)MLA{cond}

{S}UMULLRdLo,RdHi,Rm,Rs64位无符号乘法指令(RdLo,RdHi)←Rm*RsUMULL{cond}{S}UMLALRdLo,RdHi,Rm,Rs64位无符号乘加指令(RdLo,RdHi)←Rm

*Rs+(RdLo,RdHi)UMLAL{cond}{S}SMULLRdLo,RdHi,Rm,Rs64位有符号乘法指令(RdLo,RdHi)←Rm*RsSMULL{cond}{S}SMLALRdLo,RdHi,Rm,Rs64位

有符号乘加指令(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)SMLAL{cond}{S}ARM指令——乘法指令64位无符号乘加指令——UMLAL指令将Rm和Rs中的值作无符号数相乘,64位乘积与RdHi、RdLo相

加,结果的低32位保存到RdLo中,而高32位保存到RdHi中。RdLo/Hi,Rm,Rs不能为R15。RdLo/Hi,Rm必须是不同的寄存器。只影响CPSR中的N位和Z位,标志C和V不确定。指令格式如下:UMLAL{cond}{S}RdLo,RdHi,Rm,Rs应用示例:UML

ALR0,R1,R5,R8;(R1、R0)=R5×R8+(R1、R0)2022/12/5嵌入式系统原理及应用刘军芳68助记符说明操作条件码位置MULRd,Rm,Rs32位乘法指令Rd←Rm*Rs(Rd≠Rm)MUL{cond}{S}MLARd,Rm,Rs,Rn32位乘加指令Rd←Rm*Rs+Rn

(Rd≠Rm)MLA{cond}{S}UMULLRdLo,RdHi,Rm,Rs64位无符号乘法指令(RdLo,RdHi)←Rm*RsUMULL{cond}{S}UMLALRdLo,RdHi,Rm,Rs64位无符号乘加指令

(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)UMLAL{cond}{S}SMULLRdLo,RdHi,Rm,Rs64位有符号乘法指令(RdLo,RdHi)←Rm*RsSMULL{cond}{S}SMLALRdLo,RdH

i,Rm,Rs64位有符号乘加指令(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)SMLAL{cond}{S}ARM指令——乘法指令64位有符号乘法指令——SMULL指令将Rm和Rs中的值作有符号数相乘,结果的低32位保存到RdLo中,而高32位保

存到RdHi中。RdLo/Hi,Rm,Rs不能为R15。RdLo/Hi,Rm必须是不同的寄存器。只影响CPSR中的N位和Z位,标志C和V不确定。指令格式如下:SMULL{cond}{S}RdLo,RdHi,Rm,Rs应用示例:SMULLR2,R3,R7,R6;(R3、R2)=R7×

R62022/12/5嵌入式系统原理及应用刘军芳69助记符说明操作条件码位置MULRd,Rm,Rs32位乘法指令Rd←Rm*Rs(Rd≠Rm)MUL{cond}{S}MLARd,Rm,Rs,Rn32位乘加指令Rd←Rm

*Rs+Rn(Rd≠Rm)MLA{cond}{S}UMULLRdLo,RdHi,Rm,Rs64位无符号乘法指令(RdLo,RdHi)←Rm*RsUMULL{cond}{S}UMLALRdLo,RdHi,Rm,Rs64位无符号乘加指令(RdLo

,RdHi)←Rm*Rs+(RdLo,RdHi)UMLAL{cond}{S}SMULLRdLo,RdHi,Rm,Rs64位有符号乘法指令(RdLo,RdHi)←Rm*RsSMULL{cond}{S}S

MLALRdLo,RdHi,Rm,Rs64位有符号乘加指令(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)SMLAL{cond}{S}ARM指令——乘法指令64位有符号乘加指令——SMLAL指令将Rm和Rs中的值作有符号数相乘

,64位乘积与RdHi、RdLo相加,结果的低32位保存到RdLo中,而高32位保存到RdHi中。RdLo/Hi,Rm,Rs不能为R15。RdLo/Hi,Rm必须是不同的寄存器。只影响CPSR中的N位和Z位,标志C和V不确定。指令格式如下:SMLAL{cond}{S}RdLo,RdHi,Rm,Rs

应用示例:SMLALR2,R3,R7,R6;(R3、R2)=R7×R6+(R3、R2)2022/12/5嵌入式系统原理及应用刘军芳70使用乘法指令应该注意如下事项(1)在操作中使用寄存器,但R15不可用。(2)在寄存器的使用中,注意Rd不

能同时作为Rm,其它无限制。(3)有符号运算和无符号运算的低32位是没有区别的。(4)Rdlo、Rdhi和Rm必须使用不同的寄存器。(5)对于UMULL和UMLAL,即使操作数的最高位为1,也解释为无符号数。2022/12/5嵌入式系统原理及

应用刘军芳71例下列指令都是错误的:MULR1,R1,R6(Rd、Rm不为同一寄存器)MULR1,R6,[R5](指令中的所有源操作数、目的寄存器必须为通用寄存器)MLAR4,R5,R6(Rd,Rm,Rs,Rn)MULSNER6,R3,R0(S在

NE之后)UMLALR6,R4,R4,R1(Rdlo、Rdhi和Rm必须使用不同的寄存器)SMULLR5,R3,R0(Rd,Rm,Rs,Rn)MULR2,R5,#0x20(指令中的所有源操作数、目的寄存器必须为通用寄存器,不能对操作数使用立即数)2022/12/5嵌入式系统原

理及应用刘军芳724.3.2程序状态寄存器读指令ARM微处理器中的程序状态寄存器不属于通用寄存器,为了使用方便,ARM专门为程序状态寄存器设立了2条访问指令,用于在程序状态寄存器和通用寄存器之间传送数据,程序状态寄存器访问指令如表psr为CPSR或SPSR,#immed为立即数。2022/

12/5嵌入式系统原理及应用刘军芳73MRS程序状态寄存器到通用寄存器的数据传送指令图中各位的含义如下:cond:指令执行的条件R:用来区别CPSR(R=0)和SPSR(R=1)。Rd:表示目标寄存器,Rd不允许为R15。2022

/12/5嵌入式系统原理及应用刘军芳74汇编格式:MRS{<cond>}<Rd>,<CPSR|SPSR>功能:MRS指令用于将程序状态寄存器的内容传送到通用寄存器中。该指令一般用在以下情况:⑴当在异常处理或进程切换时,需要保存程序状态寄存器的值,先用该指令读出

程序状态寄存器的值,然后保存。⑵当需要改变程序状态寄存器的内容时,可用MRS将程序状态寄存器的内容读入通用寄存器,修改后再写回程序状态寄存器。例MRS指令示例:MRSR0,CPSR;传送CPSR的内容到R0MRSR0,SPSR;传送SPSR的内容到R02022/12/5嵌入式系

统原理及应用刘军芳752.MSR通用寄存器到程序状态寄存器的数据传送指令图中各位的含义如下:cond:指令执行的条件R:用来区别CPSR(R=0)和SPSR(R=1)。Field_mask:域屏蔽immed:8位立即数Rm:操作数寄存器2022/12/5嵌入式系统原理及应用刘军芳76汇编

格式:MSR{<cond>}<CPSR|SPSR>_<fields>,<Rm|#immed>功能:MSR指令用于将操作数的内容传送到程序状态寄存器的特定域中。其中,状态寄存器是指CPSR或SPSR,一般指当前工作模式下的状态寄存器。操作数可以为通用寄存器Rm或立即数#imm

ed。域<fields>用于设置程序状态寄存器中需要操作的位,32位的程序状态寄存器可分为4个域,如图所示:位[31:24]为条件标志位域,用f表示;位[23:16]为状态位域,用s表示;位[15:8]为扩

展位域,用x表示;位[7:0]为控制位域,用c表示;2022/12/5嵌入式系统原理及应用刘军芳77位域的表示方法:在CPSR或SPSR后面使用一下划线,然后是位域。上述位域可以任意组合,之间不用隔点,必须小写才有效。例如C

PSR_c和CPSR_cxsf都是正确的表达式。该指令通常用于恢复或改变程序状态寄存器的内容,在使用时,一般要在MSR指令中指明将要操作的域。例MSR指令示例:MSRCPSR,R0;传送R0的内容到CPSRMSRSPSR,R0;传送R0的内容到SPSRMSRCPSR_c

,R0;传送R0的内容到CPSR;仅修改CPSR中的控制位域2022/12/5嵌入式系统原理及应用刘军芳78将MRS和MSR指令结合起来可以对程序状态寄存器进行修改,从而可以实现处理器模式转换,设置异常中断的开和关。正确的修改方法是对状态寄存器进行

读,然后修改,再写入状态寄存器。例如,下列指令序列说明了使能IRQ中断的过程:MRSR1,CPSRBICR1,R1,#0x80MSRCPSR_c,R1MRS指令先把CPSR的值复制到R1,然后使用BIC清除R1的位7;再使用MSR把R1

的值复制到CPSR,从而实现了使能IRQ中断的功能。这个例子中只是修改了控制域的I位,而没有修改其它位。该例是在SVC模式下执行。在用户模式下可以读取CPSR,但是只能更改条件标志域f。2022/12/5嵌入式系统原理及应用刘军芳79ARM指令集——分支指令在ARM中有两种方式可以实

现程序的跳转,一种是使用分支指令直接跳转,另一种则是直接向PC寄存器赋值实现跳转。分支指令有以下四种:分支指令B;带链接的分支指令BL;带状态切换的分支指令BX。带返回和状态切换的分支指令BLX。2022/12

/5嵌入式系统原理及应用刘军芳80分支指令B/BL指令编码格式指令执行的条件码L区别B指令(L为0)和BL指令(L为1)24位有符号立即数(偏移量)•分支指令BX指令编码格式指令执行的条件码Rm目标地址寄存

器,该寄存器装载跳转地址2022/12/5嵌入式系统原理及应用刘军芳81助记符说明操作条件码位置Blabel分支指令PC←labelB{cond}BLlabel带链接的分支指令LR←PC-4,PC←labelBL{cond}BXRm带状态切换的分支指令PC←Rm,切换处理器状态BX{co

nd}ARM指令——分支指令分支指令——B指令,该指令跳转范围限制在当前指令的±32M字节地址内(ARM指令为字对齐,最低2位地址固定为0)。指令格式如下:B{cond}Label应用示例:BWAITA;跳转到WAITA标号处B

0x1234;跳转到绝对地址0x1234处2022/12/5嵌入式系统原理及应用刘军芳82例B指令示例:backwordSUBRl,R1,#1CMPR1,#0;比较R1和0BEQforward;如果R1=0则跳转到;forward处执行SUBR1,R2,#3SUBR1,R1,#1

forwardADDR1,R2,#4ADDR2,R3,#2Bbackword;程序无条件跳转到;backword处执行2022/12/5嵌入式系统原理及应用刘军芳83BLLabelxxxxxxLabelxxxMO

VPC,LRAddr1Addr2xxxxxxLRPC助记符说明操作条件码位置Blabel分支指令PC←labelB{cond}BLlabel带链接的分支指令LR←PC-4,PC←labelBL{cond}BXR

m带状态切换的分支指令PC←Rm,切换处理器状态BX{cond}ARM指令——分支指令带链接的分支指令——BL指令适用于子程序调用,使用该指令后,下一条指令的地址被拷贝到R14(即LR)连接寄存器中,然后跳转到指定地址运行程序。

跳转范围限制在当前指令的±32M字节地址内。指令格式如下:BL{cond}LabelAddr1LabelAddr2Addr21.当程序执行到BL跳转指令时,硬件将下一条指令的地址Addr2装入LR寄存器,并把跳转地址装入程序

计数器(PC)2.程序跳转到目标地址Label继续执行,当子程序执行结束后,将LR寄存器内容存入PC,返回调用函数继续执行应用示例(调用子程序):BLLabel2022/12/5嵌入式系统原理及应用刘军芳84例BL指令示例…BLfunc;跳转到子程序ADDR1,R2,#2;

子程序调用完返回后执行的语句,;返回地址…func;子程序…;子程序代码MOVR15,R14;复制返回地址到PC,;实现子程序的返回2022/12/5嵌入式系统原理及应用刘军芳85助记符说明操作条件码位置Blabel分支指令PC←labelB{cond}BL

label带链接的分支指令LR←PC-4,PC←labelBL{cond}BXRm带状态切换的分支指令PC←Rm,切换处理器状态BX{cond}ARM指令——分支指令带状态切换的分支指令——BX指令,该指令可以根据跳转地址(Rm)的最低位来切换处理器状态。其跳转范围限制在当前指令

的±32M字节地址内(ARM指令为字对齐,最低2位地址固定为0)。指令格式如下:BX{cond}Rm跳转地址Rm[0]跳转后CPSR标志T位处理器状态00ARM11Thumb2022/12/5嵌入式系统原理及应用刘军芳86ARM指令——分支指令带状态切换的分支指

令——BX指令,该指令可以根据跳转地址(Rm)的最低位来切换处理器状态。其跳转范围限制在当前指令的±32M字节地址内(ARM指令为字对齐,最低2位地址固定为0)。Rm的位[0]不用作地址的一部分。若Rm的位[0]为1,则指令将CP

SR中的标志T置位,且将目标地址的代码解释为Thumb代码;若Rm的位[0]为0,则Rm的位[1]就不能为1。指令格式如下:BX{cond}Rm应用示例:LDRR0,ThumbFun+1;将Thumb程序的

入口地址加1存入R0BXR0;跳转到R0指定的地址ThumbFun:;并根据R0的最低位来切换处理器状态…….2022/12/5嵌入式系统原理及应用刘军芳87例BX指令示例CODE32;ARM程序段,32位编码arm1ADRR0,th

umb1+1;伪指令,把语句标号thumb1所在地址赋给R0,末位R0[0]置1,要跳转到THUMB指令集MOVLR,PC;设置返回地址BXR0;跳转ADDR1,R2,#2;返回地址处,第4条指令CODE16;THUMB

程序段,16位编码thumb1ADDR1,R3,#1;THUMB程序…BXLR;跳转到返回地址处,执行第4条指令分析:该例说明了带状态切换的子程序调用和返回的结构,ARM程序段执行MOVLR,PC语句时将返回地址保存到了LR寄存器中。执行到BX语句时,PC指向下一个要执行的语句,此时PC(R15

)中的值为下一个语句ADD指令所在的地址,并根据R0中的bit[0]实现了由ARM状态切换到Thumb状态。从而调用Thumb子程序,子程序调用完后使用BXLR指令,从而实现了子程序调用的返回并切换到ARM状态。2022/12/5嵌入式系统原理及应用刘军芳8

84、BLX指令格式:BLX目标地址BLX指令从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工作状态由ARM状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中。因此,当子程序使用T

humb指令集,而调用者使用ARM指令集时,可以通过BLX指令实现子程序的调用和处理器工作状态的切换。同时,子程序的返回可以通过将寄存器R14值复制到PC中来完成。2022/12/5嵌入式系统原理及

应用刘军芳89跳转指令的应用例1:子程序的调用BL指令在执行跳转操作的同时保存下一条指令的地址,用于从被调用的子程序中返回。……BLfunction;调用子程序function……;子程序结束后,程序将返回到这里执行……functio

n;子程序的程序体……MOVPC,LR;子程序中的返回语句2022/12/5嵌入式系统原理及应用刘军芳90例2:条件执行实现类似于C语言中的if-else功能的代码段,下例的功能为求最大公约数。C语言代码为:intgcd(inta,intb){while(a!=b){if(a>b)a

=a-b;elseb=b-a;}returna;}对应的ARM汇编代码段。(代码执行前R0中存放a,R1中存放b;代码执行后R0中存放最大公约数。gcdCMPR0,R1;比较a和b的大小SUBGTSR0,R0,R1;if(a>b)a=a-bSUBLTSR1,R

1,R0;if(b>a)b=b-aBNEgcd;if(a!=b)跳转到gcd继续执行MOVPC,LR;子程序结束,返回2022/12/5嵌入式系统原理及应用刘军芳91循环结构MOVR1,#10LOOP……;循环体SUBSR

1,R1,#1BNELOOP……2022/12/5嵌入式系统原理及应用刘军芳92例3:循环语句将内存中从0x400800开始的100个字数据相加,其结果存于R3、R2中(R3中为高32位)。LDRR0,=0x

400800MOVR1,#100;初始化循环次数MOVR2,#0MOVR3,#0loop;循环体LDRR4,[R0],#4ADDSR2,R2,R4ADCR3,R3,#0SUBSR1,R1,#1;循环计数器减1,设置条件标志BNEloop;循环计数器不为

0,跳到loop继续执行……;循环计数器为0,程序继续执行2022/12/5嵌入式系统原理及应用刘军芳93if(a>b)a++;elseb++;cmpr0,r1addhir0,r0,1addlsr1,r1,1if(a!=10)&&(b!=20)a=a+b;cmp

r0,#10cmpner1,#20addner0,r0,r12022/12/5嵌入式系统原理及应用刘军芳944.3.4加载/存储指令ARM微处理器支持加载/存储指令用于在寄存器和存储器之间传送数据,加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。数

据加载与存储指令共有三种类型:单寄存器加载与存储指令、多寄存器加载与存储指令和交换指令。2022/12/5嵌入式系统原理及应用刘军芳95数据加载与存储(Load-store)指令用于在存储器和处理器的寄存器之间传送数据

。2022/12/5嵌入式系统原理及应用刘军芳96常用的单一加载存储指令如下:—LDR字数据加载指令—LDRB字节数据加载指令—LDRH半字数据加载指令—STR字数据存储指令—STRB字节数据存储指令—STRH半字数据存储指令2022/12/5嵌入式系统原理及应用刘军芳

97单一数据加载/存储指令(续1)1、LDR指令LDR指令的格式为:LDR{条件}目的寄存器,<存储器地址>LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。

LDR/STR寻址方式非常灵活,由两部分组成,一部分为一个基址寄存器,可以为任何一个通用寄存器,另一部分为地址量,有以下三种格式。(1)立即数:可以为一个无符号数,将这个数加载到基址寄存器。立即数的规定:立即数

绝对值不大于4095的数值,可使用带符号数,即在-4095~+4095之间。(4096D=1000H)LDRR0,0xFF;将的0xFF字数据读入寄存器R0。2022/12/5嵌入式系统原理及应用刘军芳98单一数据加载/存储指令(续2)(2)寄存器:寄存器中的

数值加载到基址寄存器LDRR0,[R1,R2]!;将新地址R1+R2写入R1。LDRR0,[R1,#8]!;将新地址R1+8写入R1。注意:使用后缀“!”表示,将结果写会到基址寄存器,且此时基址寄存器的值不允许为R15。(3)寄存器及移位常数:寄存器移位

后的值加载到基址寄存器LDRR0,[R1,R2,LSL#2]!;将新地址R1+R2×4写入R1。(4)其他情况LDRR0,[R1],R2;将新地址R1+R2写入R1。LDRR0,[R1],R2,LSL#2;将新地址R1+R2×4写入R1。2022/12/5

嵌入式系统原理及应用刘军芳99使用移位时需注意使用寄存器移位的方法计算偏移量时,移位的位数不能超过规定的数值,而且不能用寄存器表示移位的位数。各类移位指令的移位位数规定如下:ASR#n:算术右移(1≤n≤32)LSL#n:逻辑左移(0≤

n≤31)LSR#n:逻辑右移(1≤n≤32)ROR#n:循环右移(1≤n≤31)2022/12/5嵌入式系统原理及应用刘军芳100单一数据加载/存储指令(续3)2、LDRB指令LDRB指令的格式为:LDR{条

件}B目的寄存器,<存储器地址>LDRB指令用于从存储器中将一个8位的字节数据传送到目的寄存器中,同时将寄存器的高24位清零。该指令通常用于从存储器中读取8位的字节数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储

器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。LDRBR0,[R1];将存储器地址为R1的字节数据读入寄存器R0,并将R0的高24位清零。LDRBR0,[R1,#8];将存储器地址为R1+8的字节数据读入寄存器R0,并将R0的

高24位清零。2022/12/5嵌入式系统原理及应用刘军芳101单一数据加载/存储指令(续4)3、LDRH指令LDRH指令的格式:LDR{条件}H目的寄存器,<存储器地址>LDRH指令用于从存储器中将一个16位的半字数据传送到目的寄存器中,同时将寄存器的高1

6位清零。该指令通常用于从存储器中读取16位的半字数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。LDRHR0,[R1];将存储器地址为R1的半字数据读入寄存器R0,并将R0的高16位清零。

LDRHR0,[R1,#8];将存储器地址为R1+8的半字数据读入寄存器R0,并将R0的高16位清零。LDRHR0,[R1,R2];将存储器地址为R1+R2的半字数据读入寄存器R0,并将R0的高16位清零。2022/12/5嵌入式系统原理及应用刘军芳102单一数据加

载/存储指令(续4)4、STR指令STR指令的格式为:STR{条件}源寄存器,<存储器地址>STR指令用于从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常用,且寻址方式灵活多样,使用方式可参考指令LDR。STRR0,[R1],#8;将R0中的

字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1。STRR0,[R1,#8];将R0中的字数据写入以R1+8为地址的存储器中。2022/12/5嵌入式系统原理及应用刘军芳103单一数据加载/存储指令(续5)5、STRB指令STR

B指令的格式为:STR{条件}B源寄存器,<存储器地址>STRB指令用于从源寄存器中将一个8位的字节数据传送到存储器中。该字节数据为源寄存器中的低8位。STRBR0,[R1];将寄存器R0中的字节数据写入以R1为地址的存储器中。STRBR0,[R1,#8];将寄存

器R0中的字节数据写入以R1+8为地址的存储器中。2022/12/5嵌入式系统原理及应用刘军芳104单一数据加载/存储指令(续6)6、STRH指令STRH指令的格式为:STR{条件}H源寄存器,<存储器地址>STRH指令用于从源寄存器中将一个16位的半

字数据传送到存储器中。该半字数据为源寄存器中的低16位。STRHR0,[R1];将寄存器R0中的半字数据写入以R1为地址的存储器中。STRHR0,[R1,#8];将寄存器R0中的半字数据写入以R1+8为地址的存储器中。2022/12/5嵌入式系统原理及应用刘军芳105例LDR指令示例:;

使用标号LDRR4,START;将存储地址为START的字数据读入R4STRR5,DATA1;将R5存入存储地址为DATA1中;前索引LDRR0,[R1];将存储器地址为R1的字数据读入寄存器R0。LDRR0,[R1,R2];将存储器地址为

R1+R2的字数据读入寄存器R0。LDRR0,[R1,#8];将存储器地址为R1+8的字数据读入寄存器R0。LDRR0,[R1,R2,LSL#2];将存储器地址为R1+R2×4的字数据读入寄存器R0。;自动索引STRR0,[R1

,R2]!;将R0字数据存入存储器地址为R1+R2的存储单元中,;并将新地址R1+R2写入R1。STRR0,[R1,#8]!;将R0字数据存入存储器地址为R1+8的存储单元中,;并将新地址R1+8写入R1STR

R0,[R1,R2,LSL#2]!;将R0字数据存入地址为R1+R2×4的存储单元中,;并将新地址R1+R2×4写入R1。2022/12/5嵌入式系统原理及应用刘军芳106;后索引LDRR0,[R1],#8;将存储器地址为R1的字数据读入寄存器R0,;并将新地址R1+8写入R1LDRR

0,[R1],R2;将存储器地址为R1的字数据读入寄存器R0,;并将新地址R1+R2写入R1。LDRR0,[R1],R2,LSL#2;将存储器地址为R1的字数据读入;寄存器R0,并将新地址;R1+R2×4写入R1。2022/12

/5嵌入式系统原理及应用刘军芳107例3.42指令的正误LDRR1,[R2,R5]!;正确STRR2,[R3],#0xFFFF8;错误,超出了立即数的范围STREQR4,[R0,R4,LSLR5];错误,不能用寄存器表示移位的位数LDRR4,[R0,R1,LSL#32];错

误,超出了移位的范围STREQR3,[R6],#-0x08;正确LDRR0,[R2]!,-R6;错误,后索引不用!后缀LDRR4,START;正确LDRR1,[SP,#-0x04];正确STRR1,START;格式

正确,但必须保证标号处可以;存储数据LDRPC,R6;错误,R6不表示一个存储地址LDRPC,[R6];正确LDRR1,[R3,R15];错误,R15不可作为偏移寄存器2022/12/5嵌入式系统原理及应用刘军芳108批量数据加载/存储指令多寄存器加载

与存储指令也称为批量数据加载/存储指令,ARM微处理器所支持批量数据加载/存储指令可以一次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据加载到多个寄存器,批量数据存储指令则完成相反的操作。多寄存器加载与存储指令在数据块

操作、上下文切换、堆栈操作等方面,比单寄存器加载与存储指令会有更高的执行效率。2022/12/5嵌入式系统原理及应用刘军芳109批量数据加载/存储指令常用的加载存储指令如下:—LDM批量数据加载指令—STM批量数据存储指令LDM(或STM)指令LDM(或STM)

指令的格式为:LDM(或STM){条件}{类型}基址寄存器{!},寄存器列表{∧}LDM(或STM)指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内

容入栈或出栈。2022/12/5嵌入式系统原理及应用刘军芳110批量数据加载/存储指令(续1)其中,{类型}为以下几种情况:IA每次传送后地址加4;IB每次传送前地址加4;DA每次传送后地址减4;DB每次传送前地址减4;FD满递减堆栈;ED空递减堆栈;FA满递增堆栈;EA空递

增堆栈;2022/12/5嵌入式系统原理及应用刘军芳111LDM/STM指令依据其后缀名(如IA、IB)的不同,其寻址的方式也有很大不同。2022/12/5嵌入式系统原理及应用刘军芳112批量数据加载/存储指令(续1){!}

为可选后缀,若选用该后缀,则当数据传送完毕之后,将最后的地址写入基址寄存器,否则基址寄存器的内容不改变。基址寄存器不允许为R15,寄存器列表可以为R0~R15的任意组合。{∧}为可选后缀,当指令为LDM且寄存器列表中包含R15,选用该后缀时表示

:除了正常的数据传送之外,还将SPSR复制到CPSR。同时,该后缀还表示传入或传出的是用户模式下的寄存器,而不是当前模式下的寄存器。STMFDR13!,{R0,R4-R12,LR};将寄存器列表中的寄存器(R0

,R4到R12,LR)存入堆栈。LDMFDR13!,{R0,R4-R12,PC};将堆栈内容恢复到寄存器(R0,R4到R12,PC)。2022/12/5嵌入式系统原理及应用刘军芳113例设执行前:R0=0x000

90010、R6=R7=R8=0x00000000,存储器地址为0x00090010存储的内容如图所示,则分别执行指令LDMIAR0!,{R6-R8},LDMIBR0!,{R6-R8}各相关寄存器值的变化分别如何?2022/12/5嵌入式系统原理及应用刘军

芳114LDMIA指令执行后LDMIB指令执行后2022/12/5嵌入式系统原理及应用刘军芳115堆栈操作堆栈的一端是固定的,另一端是浮动的。堆栈固定端是堆栈的底部,称为栈底。堆栈浮动端可以推入或弹出数据。向堆栈推入数据时,

新推入的数据堆放在以前推入数据的上面,而最先推入的数据被推至堆栈底部,最后推入的数据堆放在堆栈顶部,这称为栈顶。从堆栈弹出数据时,堆栈顶部数据最先弹出,而最先推入的数据则是最后弹出。由于堆栈顶部是浮动

的,为了指示现在堆栈中存放数据的位置,通常设置一个堆栈指针SP(R13),它始终指向堆栈的顶部。这样,堆栈中数据的进出都由SP来“指挥”。当一个数据(32位)推入堆栈时,SP(R13的值减4)向下浮动指向下一个地址,即新的栈顶。当数据从堆栈中弹出时,SP(R13的值加4)向上浮

动指向新的栈顶。2022/12/5嵌入式系统原理及应用刘军芳116堆栈的操作包括建栈、进栈、出栈三种基本操作。(1)建栈建栈就是规定堆栈底部在RAM存储器中的位置,如:用户可以通过LDR命令设置SP的值来建立堆栈。LDRR1

3,=0x90010LDRSP,=0x90010这时,SP指向地址0x90010,栈中无数据,堆栈的底部与顶部是重叠,是一个空栈。2022/12/5嵌入式系统原理及应用刘军芳117(2)进栈ARM体系结构中使用多寄存器指令来完成堆栈操作。出栈使用LDM指令,进栈使用STM指令。LDM和STM指

令往往结合下面一些参数实现堆栈的操作。FD满递减堆栈ED空递减堆栈FA满递增堆栈EA空递增堆栈在使用一个堆栈的时候,需要确定堆栈在存储器空间中是向上生长还是向下生长的。向上称为递增(Ascending),向下称为递减(D

escending)。2022/12/5嵌入式系统原理及应用刘军芳118ARM制定了ARM-Thumb过程调用标准(ATPCS),定义了例程如何被调用,寄存器如何被分配。在ATPCS中,堆栈被定义为满递减式堆栈,因

此LDMFD和STMFD指令分别用来支持POP操作(出栈)和PUSH操作(进栈)。进栈(PUSH)操作就是把数据推入堆栈的操作。ARM中进栈或出栈操作都是以字(32位)为单位的.2022/12/5嵌入式系统原理及应用刘军芳119例下列

指令说明了进栈和出栈的过程,设指令执行之前SP=0x00090010(R13),R4=0x00000003,R3=0x00000002,R2=0x00000001,将R2-R4入栈,然后出栈,注意进栈和出栈后SP的值?STMFDSP!,{R2-R4}LDMFDSP!,

{R6-R8}2022/12/5嵌入式系统原理及应用刘军芳120分析:第一条指令将R2-R4的数据入栈,指令执行前SP的值为0x00090010,指令执行时SP指向下一个地址(SP-4)存放R4,然后依次存放R3、R2,数据入栈后SP的值为0x000

90004,指向堆栈的满位置,如果有数据继续入栈则下一地址为0x90000。其过程如图所示,注意入栈的顺序。第二条指令实现退栈操作,在第一条指令的基础上,表示将刚才入栈的数据分别退栈到R6-R8,退栈后SP指向0x00090010。实际上STMFD指令相当于

STMDB指令,LDMFD指令相当于LDMIA指令。2022/12/5嵌入式系统原理及应用刘军芳121数据交换指令ARM微处理器所支持数据交换指令能在存储器和寄存器之间交换数据。数据交换指令是数据加载与存储指令的一种

特例,交换指令是一个原子操作,在操作期间阻止其它任何指令对该存储单元的读/写。数据交换指令有如下两条:—SWP字数据交换指令—SWPB字节数据交换指令2022/12/5嵌入式系统原理及应用刘军芳1221.SWP字数据交换指令汇编格式:

SWP{<cond>}<Rd>,<Rm>,[<Rn>]功能:SWP指令用于将寄存器Rn所指向的存储器中的字数据加载到目的寄存器Rd中,同时将源寄存器Rm中的字数据存储到寄存器Rn所指向的存储器中,即Rd=[Rn],[Rn]=Rm。显然,当寄存器

Rm和目的寄存器Rd为同一个寄存器时(两者应与Rn不同),指令交换该寄存器和存储器的内容。2022/12/5嵌入式系统原理及应用刘军芳123例SWP指令示例:SWPR0,R1,[R2];将R2所指向的存储器中的字数;据加载到R0,同时将R1中的字;数据存储到R2所

指向的存储单元。SWPR0,R0,[R1];将R1所指向的存储器中的字数据;与R0中的字数据交换。2022/12/5嵌入式系统原理及应用刘军芳1242.SWPB字节数据交换指令汇编格式:SWPB{<cond>}<Rd>,<Rm>,[<Rn>]功

能:SWPB指令用于将寄存器Rn所指向的存储器中的字节数据加载到目的寄存器Rd中,目的寄存器的高24清零,同时将源寄存器Rm中的低8位数据存储到寄存器Rn所指向的存储器中。显然,当寄存器Rm和目的寄存器Rd为同一个

寄存器时(两者应与Rn不同),指令交换该寄存器和存储器的内容。2022/12/5嵌入式系统原理及应用刘军芳125例SWPB指令示例:SWPBR0,R1,[R2];将R2所指向的存储器中的字节;数据加载到R0,R0的高24位清;零,同

时将R1中的低8位数据存;储到R2所指向的存储单元。SWPBR0,R0,[R1];将R1所指向的存储器中的字节;数据与R0中的低8位数据交换。2022/12/5嵌入式系统原理及应用刘军芳126使用SWP和SWPB指令时需要注意:(1

)PC不能用作指令中的任何寄存器。(2)基址寄存器Rn不应与源寄存器Rm或目的寄存器Rd相同,但是Rm和Rd可以相同。(3)寄存器位置不可为空,必须满足3个寄存器。2022/12/5嵌入式系统原理及应用刘军芳1274.3.6异常产生指令ARM微处理器所支持的异常指令有如下两条:—S

WI软件中断指令—BKPT断点中断指令2022/12/5嵌入式系统原理及应用刘军芳1281、SWI指令SWI指令的格式为:SWI{条件}24位的立即数SWI指令用于产生软件中断,以便用户程序能调用操作系统的系统例程。处理器模式改变为超

级用户模式,CPSR寄存器保存到超级用户模式下的SPSR寄存器,并且跳转到SWI向量操作系统在SWI的异常处理程序中提供相应的系统服务,指令中24位的立即数指定用户程序调用系统例程的类型,相关参数通过通用寄存器传

递,当指令中24位的立即数被忽略时,用户程序调用系统例程的类型由通用寄存器R0的内容决定,同时,参数通过其他通用寄存器传递。SWI0x02;该指令调用操作系统编号位02的系统例程。异常产生指令(续1)2022/12/5嵌入式系统原理及应用刘军芳129说明:(1)软件中断进入的是管理模

式,中断后会改变程序状态寄存器中的相关位。(2)中断后处理器把0x00000008赋给PC,并把中断处地址保存在LR中,把CPSR保存在SPSR中。(3)SWI_number是向中断服务程序传递一个参数。不需要传递参数时,应该把表达式写作0,表达式不可省略。2022/12/5嵌入式系统原理及应用

刘军芳130SWI的调用当程序执行这条语句时,将进入异常中断。此时,需要把ARM处理器从用户模式改变到管理模式。执行这条指令,ARM处理器硬件会实现下列操作:(1)把中断处的地址值(PC-4)拷贝到R14中,保留中断处地址;(2)把CP

SR拷贝到SWI模式的SPSR,保存状态寄存器的值;(3)把状态寄存器的其他模式改变成管理模式;(4)把中断向量0x00000008赋值给PC;(5)禁止IRQ中断,使CPSR[7]=1。随后,程序执行0x00000008处的指令,通常是一个跳转指令或PC赋值指令。2022

/12/5嵌入式系统原理及应用刘军芳1312、BKPT指令BKPT指令的格式为:BKPT16位的立即数BKPT指令生软件断点中断,可用于程序的调试,v5T及以上体系使用。断点指令用于软件调试;它使处理器停止执行正常指令而进入相应的调试程序。BKPT0XF010异常产生指令(续2)2022

/12/5嵌入式系统原理及应用刘军芳1324.4Thumb指令及应用2022/12/5嵌入式系统原理及应用刘军芳133ARM指令和Thumb指令的比较ARM指令和Thumb指令的比较ARM指令和Thum

b指令的比较如图所示,图中的纵坐标是测试向量Dhrystone在20MHz频率下运行1秒钟的结果,其值越大表明性能越好;横坐标是系统存储器系统的数据总线宽度。由图可知,当系统具有32位的数据总线宽度时,ARM比Thumb有更好的性能表现。当系统的数据总线宽度小于

32位时,Thumb比ARM的性能更好。2022/12/5嵌入式系统原理及应用刘军芳134每一条Thumb指令都和一条32位的ARM指令相关,图显示了一条Thumb加法指令ADD译码成等效的ARM加法指令。2022/12/5嵌入式系

统原理及应用刘军芳1352022/12/5嵌入式系统原理及应用刘军芳1362022/12/5嵌入式系统原理及应用刘军芳137从上面两个表可以看出,不能直接访问cpsr和spsr。换句话说,没有与MSR

和MRS等价的Thumb指令。为了改变cpsr和spsr的值,必须切换到ARM状态,使用MSR和MRS来实现。2022/12/5嵌入式系统原理及应用刘军芳1384.4Thumb指令及应用为兼容数据总线宽度为16位的应用系统,ARM体系结构除了支持执行效率很高

的32位ARM指令集以外,同时支持16位的Thumb指令集。Thumb指令集是ARM指令集的一个子集,允许指令编码为16位的长度。与等价的32位代码相比较,Thumb指令集在保留32代码优势的同时,大大的节省了系统的存储空间。所有的Thumb指令都有对应的ARM指令,而且Thumb的编程模型也对

应于ARM的编程模型,在应用程序的编写过程中,只要遵循一定调用的规则,Thumb子程序和ARM子程序就可以互相调用。2022/12/5嵌入式系统原理及应用刘军芳139与ARM指令集相比较,Thumb指令集中的数据处理指令的操作数仍

然是32位,指令地址也为32位,但Thumb指令集为实现16位的指令长度,舍弃了ARM指令集的一些特性,如大多数的Thumb指令是无条件执行的,而几乎所有的ARM指令都是有条件执行的;大多数的Thumb数据处理

指令的目的寄存器与其中一个源寄存器相同。2022/12/5嵌入式系统原理及应用刘军芳1404.4Thumb指令及应用—Thumb代码所需的存储空间约为ARM代码的60%~70%—Thumb代码使用的

指令数比ARM代码多约30%~40%—若使用32位的存储器,ARM代码比Thumb代码快约40%—若使用16位的存储器,Thumb代码比ARM代码快约40%~50%—与ARM代码相比较,使用Thumb代码,存储器的功耗会降低约30%2022/12/5嵌入式系统原理

及应用刘军芳141ARM指令集和Thumb指令集各有其优点,若对系统的性能有较高要求,应使用32位的存储系统和ARM指令集,若对系统的成本及功耗有较高要求,则应使用16位的存储系统和Thumb指令集。

当然,若两者结合使用,充分发挥其各自的优点,会取得更好的效果。2022/12/5嵌入式系统原理及应用刘军芳1421、Thumb指令集没有协处理器指令、信号量指令、以及访问CPSR或SPSR的指令,没有乘加指令

及64位乘法指令等,且指令的第二操作数受到限制;2、大多数的Thumb数据处理指令采用2地址格式;3、除了跳转指令B有条件执行功能之外,其他指令均为无条件执行,而且分支指令的跳转范围有更多限制;4、数据处理指令是对通用寄存器进行操作,在大

多数情况下,操作的结果放入其中一个操作数寄存器中,而不是放入第3个寄存器中;访问寄存器R8~R15受到一定的限制,除MOV、ADD指令访问R8~R15外,其他数据处理指令总是更新CPSR中ALU状态标志,访问寄存器R8~R15的Thumb数据处理指令不能更新CPSR中的ALU状态指示。20

22/12/5嵌入式系统原理及应用刘军芳1435、Thumb状态下,单寄存器加载和存储指令只能访问寄存器R0~R7;6、LDM、STM指令可以将任何范围为R0~R7的寄存器子集加载或存储;7、PUSH、POP指令使用栈寄存器R13作为基址堆栈操作。2022/12/5

嵌入式系统原理及应用刘军芳144数据处理指令数据处理指令可以操作寄存器中的数据,包括MOV指令、算术指令、移位指令、逻辑指令、比较指令和乘法指令。Thumb数据处理指令是ARM数据处理指令的一个子集,因此其使用格式可参考相关的ARM数据处理指令。2022/12/5嵌入式系统原理及应用

刘军芳145大多数的Thumb数据处理指令操作寄存器R0~R7,同时更新CPSR。但下列指令例外:MOVRd,RnADDRd,RmCMPRn,RmADDsp,#immediateSUBsp,#immediateADDRd,sp,#immediateADDRd,pc,#immediate这些

指令可以操作R8~R14和PC。2022/12/5嵌入式系统原理及应用刘军芳146单寄存器加载和存储指令Thumb指令集支持寄存器的加载和存储,即LDR和STR指令。这些指令使用2种前变址寻址方式:

寄存器偏移和立即数偏移。单寄存器加载和存储指令如表所示。2022/12/5嵌入式系统原理及应用刘军芳147多寄存器加载和存储指令Thumb指令集的多寄存器加载和存储(load-store)指令是ARM指令集的多寄存器加载和存储指令的简化形式。多

寄存器加载和存储指令如表所示。Thumb指令集中的多寄存器加载和存储指令只支持后增量(IA,IncrementAfter)寻址方式。其语法格式如下:LDM|STMIARn!,{lowregisterlist:R0~R7}2

022/12/5嵌入式系统原理及应用刘军芳148这里N是寄存器列表中寄存器的数目。从表中可看到,指令执行后总是更新基址寄存器,基址寄存器和可以使用的寄存器列表仅限于R0~R7。2022/12/5嵌入式系统原理及应用刘军芳149堆栈指令Thumb的堆栈操作

与等效的ARM指令是不同的,因为它们使用了更传统的POP和PUSH的概念。Thumb堆栈指令如表所示,其指令的语法格式如下:POP{low-register-list{,pc}}PUSH{low-register-list{,lr}}注意:在指令中没有堆栈指针,这是因为在Thumb操

作中,寄存器R13是固定作为堆栈指针用的,SP是自动更新的。可操作的寄存器列表仅限于寄存器R0~R7。PUSH指令可操作的寄存器还包括连接寄存器LR,同样POP指令可以操作PC。这为子程序的进入和退出提供了支持。堆栈指令仅支持递减式满堆栈操作。2022/12/5嵌入式系统原理及应用刘军芳150

2022/12/5嵌入式系统原理及应用刘军芳151例PUSH和POP指令举例BLThumbRoutine;调用子程序…;其它代码ThumbRoutinePUSH{Rl,LR};进入子程序MOVR0,#2POP{R1,PC};从子程序返

回分析:程序使用带连接的分支指令(BL)来调用子程序ThumbRoutine。连接寄存器LR和Rl被压入堆栈,在返回时,寄存器Rl的值被原来的Rl出栈恢复PC被原来入栈的LR的值覆盖。这就完成了从子程序返回。2022/12/5嵌入式系统原理及应用刘军芳152软

件中断指令与ARM指令集下的软件中断指令相似,Thumb软件中断指令(SWI)也产生一个软件中断异常。在Thumb状态下,如果有任何中断或者异常标志出现,那么处理器就会自动回到ARM状态去进行异常处

理。SWI指令的语法如下:SWIimmediateThumbSWI指令与等效的ARM指令有同样的作用和几乎完全相同的语法。区别是ThumbSWI数目限制在0~255,并且不能条件执行。2022/12/5嵌入式系统原理及应

用刘军芳1531、下列两段代码是用来实现打开中断和关闭中断,请补齐空白处内容MRSR1,CPSRBICR0,R1,____MSRCPSR_c,R0MRSR1,CPSRORRR1,_____MSRCPSR_c,R12022/12

/5嵌入式系统原理及应用刘军芳1542、下列指令在什么条件下被执行SUBMIR3,R3,#0x08ADDNER0,R0,R42022/12/5嵌入式系统原理及应用刘军芳1553、画出示意图说明进栈和出栈的过程:STMFDSP!,{R0-R7,L

R};现场保存,将R0~R7、LR入栈LDMFDSP!,{R0-R7,PC};恢复现场,异常处理返回2022/12/5嵌入式系统原理及应用刘军芳156作业P1411、2、3、4、7、82022/

12/5嵌入式系统原理及应用刘军芳1575ARM汇编语言的程序结构基于ARM的编译器一般支持汇编语言的程序设计、C/C++语言的程序设计以及两者的混合编程。本章主要介绍ARM的嵌入式系统程序设计的一些基本概念

,如ARM汇编语言的伪指令、汇编语言的语句格式和汇编语言的程序结构,同时介绍C/C++和汇编语言的混合编程问题。2022/12/5嵌入式系统原理及应用刘军芳1585.1ARM汇编器所支持伪指令ARM汇编程序由机

器指令、伪指令和宏指令组成。在ARM汇编程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作。伪指令在源程序中的作用是为完

成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。宏是一段独立的程序代码,它是通过伪指令定义的,在程序中使用宏指令即可以调用宏。在ARM的汇编程序中,有如下几种伪指令:符号定义伪指令、

数据定义伪指令、汇编控制伪指令、宏指令以及其他伪指令。2022/12/5嵌入式系统原理及应用刘军芳1595.1.1符号定义伪指令符号定义(SymbolDefinition)伪指令用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存

器的别名等操作。常见的符号定义伪指令有如下几种:-用于定义全局变量的GBLA、GBLL和GBLS。-用于定义局部变量的LCLA、LCLL和LCLS。-用于对变量赋值的SETA、SETL、SETS。-为通用寄

存器列表定义名称的RLIST。2022/12/5嵌入式系统原理及应用刘军芳1601、GBLA、GBLL和GBLS语法格式:GBLA(GBLL或GBLS)全局变量名GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量,并将其初始化。G

BLA伪指令用于定义一个全局的数字变量,并初始化为0;GBLL伪指令用于定义一个全局的逻辑变量,并初始化为F(假);GBLS伪指令用于定义一个全局的字符串变量,并初始化为空;由于是定义全局变量,因此在整个程序范围内变量名必须唯一。2022/12/5嵌入式

系统原理及应用刘军芳161例:GBLATest1;定义一个全局的数字变量,变量名为Test1Test1SETA0xaa;将该变量赋值为0xaaGBLLTest2;定义一个全局的逻辑变量,变量名为Test2Test2SETL{TRUE};将该变量赋值为真GBLSTest3;定义一个全局的字符

串变量,变量名为Test3Test3SETS“Testing”;将该变量赋值为“Testing”2022/12/5嵌入式系统原理及应用刘军芳1622、LCLA、LCLL和LCLS语法格式:LCLA(LCLL或LCLS)局部变量名LCLA、LCLL和L

CLS伪指令用于定义一个ARM程序中的局部变量,并将其初始化。LCLA伪指令用于定义一个局部的数字变量,并初始化为0;LCLL伪指令用于定义一个局部的逻辑变量,并初始化为F假;LCLS伪指令用于定义一个局部的字符串变量,并初始化为空;由于是用于声明局部变量,在其

作用范围内变量名必须唯一。2022/12/5嵌入式系统原理及应用刘军芳163LCLATest4;声明一个局部的数字变量,变量名为Test4Test4SETA0xaa;将该变量赋值为0xaaLCLLTest5;声明一个局部的逻辑变量,变量名为Test5Test

4SETL{TRUE};将该变量赋值为真LCLSTest6;定义一个局部的字符串变量,变量名为Test6Test6SETS“Testing”;将该变量赋值为“Testing”2022/12/5嵌入式系统原理及应用刘军芳1643、SETA、SETL和SETS

语法格式:变量名SETA(SETL或SETS)表达式伪指令SETA、SETL、SETS用于给一个已经定义的全局变量或局部变量赋值。其中,变量名为已经定义过的全局变量或局部变量,表达式为将要赋给变量的值。SETA伪指令用于给一个数学变量赋值;

SETL伪指令用于给一个逻辑变量赋值;SETS伪指令用于给一个字符串变量赋值;LCLATest3;声明一个局部的数字变量,变量名为Test3Test3SETA0xaa;将该变量赋值为0xaaLCLLTest4;声明一个局部的逻辑变量,变量名为T

est4Test4SETL{TRUE};将该变量赋值为真2022/12/5嵌入式系统原理及应用刘军芳1654、RLIST语法格式:名称RLIST{寄存器列表}RLIST伪指令可用于对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在ARM指令LDM/STM中使用。在LDM/STM指令中,列

表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关。RegListRLIST{R0-R5,R8,R10};将寄存器列表名称定义为RegList,可在ARM指令LDM/STM中通过该名称访问寄存器列表。2022/12

/5嵌入式系统原理及应用刘军芳1665.1.2数据定义伪指令数据定义伪指令(DataDefinition)一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。常见的数据定义伪指令有如下几种:-DCB用于分配一片连续的字节存储单元并用指定的

数据初始化。-DCW(DCWU)用于分配一片连续的半字存储单元并用指定的数据初始化。-DCD(DCDU)用于分配一片连续的字存储单元并用指定的数据初始化。2022/12/5嵌入式系统原理及应用刘军芳167

数据定义伪指令—DCFD(DCFDU)用于为双精度的浮点数分配一片连续的字存储单元并用指定的数据初始化。—DCFS(DCFSU)用于为单精度的浮点数分配一片连续的字存储单元并用指定的数据初始化。—DCQ(DCQ

U)用于分配一片以8字节为单位的连续的存储单元并用指定的数据初始—SPACE用于分配一片连续的存储单元—MAP用于定义一个结构化的内存表首地址—FIELD用于定义一个结构化的内存表的数据域2022/12/5嵌入式系统原理及应用刘军

芳1681、DCB语法格式:标号DCB表达式DCB伪指令用于分配一片连续的字节存储单元并用伪指令中指定的表达式初始化。其中,“标号”表示内存起始地址标号,“表达式”可以为-0~255的数字或字符串,同时,内存分配的

字节数由表达式决定。DCB也可用“=”代替。StrDCB0x33,0x45,0x12;分配一片连续的字节存储单元并初始化。2022/12/5嵌入式系统原理及应用刘军芳1692、DCW(或DCWU)语法格式:标号DCW(或DCWU)表达式DCW(

或DCWU)伪指令用于分配一片连续的半字存储单元并用伪指令中指定的表达式初始化。其中,“标号”表示内存起始地址标号,“表达式”可以为程序标号或数字表达式,取值范围在-32768~65535。用DCW分配的字存储单元是半字对齐的,

而用DCWU分配的字存储单元并不严格半字对齐。DataTestDCW1,2,3;分配一片连续的半字存储单元并初始化。2022/12/5嵌入式系统原理及应用刘军芳1703、DCD(或DCDU)语法格式:标号DCD(或DCDU)表达式DCD(或DCDU)伪指令用于分配一片连续的字存储单元并

用伪指令中指定的表达式初始化。其中,“标号”表示内存起始地址标号,“表达式”可以为程序标号或数字表达式。DCD也可用“&”代替。用DCD分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严格字对齐。DataTestDCD4,

5,6;分配一片连续的字存储单元并初始化。2022/12/5嵌入式系统原理及应用刘军芳1714、DCFD(或DCFDU)语法格式:标号DCFD(或DCFDU)表达式DCFD(或DCFDU)伪指令用于为双精度

的浮点数分配一片连续的字存储单元并用伪指令中指定的表达式初始化。其中,“标号”表示内存起始地址标号,每个双精度的浮点数占据两个字单元。用DCFS分配的字存储单元是字对齐的,而用DCFSU分配的字存储单元并不严格字对齐。FDataTestDCFS2E115,-5E7;分配一片连续的字存储

单元并初始化为指定的双精度数。2022/12/5嵌入式系统原理及应用刘军芳1725、DCFS(或DCFSU)语法格式:标号DCFS(或DCFSU)表达式DCFS(或DCFSU)伪指令用于为单精度的浮点数分配一片

连续的字存储单元并用伪指令中指定的表达式初始化。其中,“标号”表示内存起始地址标号,每个单精度的浮点数占据一个字单元。用DCFS分配的字存储单元是字对齐的,而用DCFSU分配的字存储单元并不严格字对齐。FDataTestDCFD2E115,-5E7;分配一片连续的

字存储单元并初始化为指定的双精度数。2022/12/5嵌入式系统原理及应用刘军芳1736、DCQ(或DCQU)语法格式:标号DCQ(或DCQU)表达式DCQ(或DCQU)伪指令用于分配一片以8个字节为单位的连续存储区域并用伪指令中指定的表达式初始化。用DCQ分配的存储

单元是字对齐的,而用DCQU分配的存储单元并不严格字对齐。DataTestDCQ100;分配一片连续的存储单元并初始化为指定的值。2022/12/5嵌入式系统原理及应用刘军芳1747、SPACE语法格式:标号SPACE表达式SPACE伪指令用于分配一片连续的存储区域并初始化

为0。其中,“表达式”为要分配的字节数。SPACE也可用“%”代替。DataSpaceSPACE100;分配连续100字节的存储单元并初始化为0。2022/12/5嵌入式系统原理及应用刘军芳1758、MAP语法格式:

MAP表达式{,基址寄存器}MAP伪指令用于定义一个结构化的内存表的首地址。MAP也可用“^”代替。“表达式”可以为程序中的标号或数学表达式,基址寄存器为可选项,当基址寄存器选项不存在时,表达式的值即为内存表的首地址;当该选项存在时,内

存表的首地址为表达式的值与基址寄存器的和。MAP0x100,R0;定义结构化内存表首地址的值为0x100+R0。2022/12/5嵌入式系统原理及应用刘军芳1769、FILED语法格式:标号FIELD表达式FIELD伪指令用于定义一个结构化内存表中的数据。FILED也可用“#”代替。

表达式的值为当前数据域在内存表中所占的字节数。FIELD伪指令常与MAP伪指令配合使用来定义结构化的内存表。MAP伪指令定义内存表的首地址,FIELD伪指令定义内存表中的各个数据域,并可以为每个数据域指定一个标号供其他的指令引用。2022/12/5嵌入式

系统原理及应用刘军芳177注意:MAP和FIELD伪指令仅用于定义数据结构,并不实际分配存储单元。MAP0x100;定义结构化内存表首地址的值为0x100。AFIELD16;定义A的长度为16字节,位置为0x100BFIELD32;定义B的长度为32字

节,位置为0x110SFIELD256;定义S的长度为256字节,位置为0x1302022/12/5嵌入式系统原理及应用刘军芳1785.1.3汇编控制伪指令汇编控制伪指令用于控制汇编程序的执行流程,常用的汇编控制伪指令包括以下几条:—IF、ELS

E、ENDIF—WHILE、WEND—MACRO、MEND—MEXIT2022/12/5嵌入式系统原理及应用刘军芳1791、IF、ELSE、ENDIF语法格式:IF逻辑表达式指令序列1{ELSE指令序列2}ENDIFIF、

ELSE、ENDIF根据条件的成立与否决定是否执行某个指令序列。IF、ELSE、ENDIF伪指令可以嵌套使用。2022/12/5嵌入式系统原理及应用刘军芳180GBLLTest;声明一个全局的逻辑变量,变量名为Test...IFTest=TR

UE指令序列1ELSE指令序列2ENDIF2022/12/5嵌入式系统原理及应用刘军芳1812、WHILE、WEND语法格式:WHILE逻辑表达式指令序列WENDWHILE、WEND根据条件的成立与否决定是否循环执行某个指令序

列。WHILE、WEND伪指令可以嵌套使用。2022/12/5嵌入式系统原理及应用刘军芳182GBLACounter;声明一个全局的数字变量,变量名为CounterCounterSETA3;由变量Counter控制循环次数..WHILEC

ounter<10指令序列WEND2022/12/5嵌入式系统原理及应用刘军芳1833、MACRO、MEND语法格式:MACRO$标号宏名$参数1,$参数2,..宏定义体MENDMACRO、MEND伪指令可以将一段代码定义为一个整体,称为宏指令,然后就可以在程序中通过宏

指令多次调用该段代码。其中,在宏指令被展开时,$标号会被替换为用户定义的符号。包含在MACRO和MEND之间的指令序列称为宏定义体。2022/12/5嵌入式系统原理及应用刘军芳184宏指令可以使用一个或多个参数,当汇编器将宏指令被展开时,这些参数被相应的值替换。宏指令的使用方式和功能与子

程序有些相似,子程序可提供模块化的程序设计、节省存储空间并提高运行速度,但在使用时需保护现场,增加了系统开销。因此,在代码较短且需要传递的参数较多时,可使用宏指令代替子程序。MACRO、MEND伪指令可以嵌套使用2022/12/5嵌入式

系统原理及应用刘军芳185宏应用例子2022/12/5嵌入式系统原理及应用刘军芳186汇编预处理后,宏调用被展开2022/12/5嵌入式系统原理及应用刘军芳1874、MEXIT语法格式:MEXITMEXIT用于从宏定义中跳转出去。2022/12/5嵌入式系统原理及应用刘军芳188

5.1.4其他常用的伪指令1、AREA语法格式:AREA段名{,属性1}{,属性2}⋯⋯AREA伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用“|”括起来,如|1_test

|。常用的属性如下所示:—CODE属性:用于定义代码段,默认为READONLY。—DATA属性:用于定义数据段,默认为READWRITE。—READONLY属性:指定本段为只读,代码段默认为READONLY。2022/12

/5嵌入式系统原理及应用刘军芳189—READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。—ALIGN属性:使用方式为ALIGN表达式。—COMMON属性:该属性定

义一个通用的段,不包含任何的用户代码和数据。—NOINIT属性,指定该数据段仅仅保留了内存单元,而没有将初始值写入内存单元,或将内存单元初始化为零。2022/12/5嵌入式系统原理及应用刘军芳1901、AREA一个汇编语言程序

至少要包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。AREAInit,CODE,READONLY指令序列;该伪指令定义了一个代码段,段名为Init,属性为只读。AREAdata,DATA,

READWRITE指令序列;该伪指令定义了一个数据段,段名为data,属性为可读可写。2022/12/5嵌入式系统原理及应用刘军芳1912、ALIGN语法格式:ALIGN{表达式{,偏移量}}ALIGN伪指令可通过添加填充字节的方式,使当前位置满足一定的对其方式。表达

式的值用于指定对齐方式,可能的取值为2的幂,如1、2、4、8、16等。若未指定表达式,则将当前位置对齐到下一个字的位置。偏移量也为一个数字表达式,若使用该字段,则当前位置的对齐方式为:2的表达式次幂+偏移量。AREAInit,CODE,READONLY,ALIEN

=3;指定后面的指令为8字节对齐。2022/12/5嵌入式系统原理及应用刘军芳192对齐现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问

特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。通常,我们写程序的时候,不需要考虑对齐问题。编译器会替我们选择适合目标平台的对齐策略。当然,我们也可以通知给编译器传

递预编译指令而改变对指定数据的对齐方法。2022/12/5嵌入式系统原理及应用刘军芳193对齐的作用和原因各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐

,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低字节进行拼凑

才能得到该int数据。显然在读取效率上下降很多。这也是空间和时间的博弈。2022/12/5嵌入式系统原理及应用刘军芳1943、CODE16、CODE32语法格式:CODE16(或CODE32)CODE16伪指令通

知编译器,其后的指令序列为16位的Thumb指令。CODE32伪指令通知编译器,其后的指令序列为32位的ARM指令。CODE16和CODE32只是指示编译器其后指令的类型,并不能对处理器进行状态的切换。2022/12/5嵌入式系统原理及应用刘军芳195AREA

Init,CODE,READONLY..CODE32;通知编译器其后的指令为32位的ARM指令32位ARM指令代码段..CODE16;通知编译器其后的指令为16位的Thumb指令16位ARM指令代码段..END;程序结束2022/12/5嵌入式系

统原理及应用刘军芳1964、ENTRY格式:ENTRY用途:用于指定汇编语言程序的入口地址。在一个完整的汇编语言程序中至少有一个ENTRY,但在一个原文件里最多只能有一个ENTRY(可以没有)。

实例:AREAInit,CODE,READONLYENTRY…….2022/12/5嵌入式系统原理及应用刘军芳1975、END语法格式:ENDEND伪指令用于通知编译器已经到了源程序的结尾。A

REAInit,CODE,READONLY..END;指定应用程序的结尾2022/12/5嵌入式系统原理及应用刘军芳1986、EQU语法格式:名称EQU表达式{,类型}EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于C语言中的#define。其中EQU可用

“*”代替。“名称”为EQU伪指令定义的字符名称,当表达式为32位的常量时,可以指定表达式的数据类型,可以有以下三种类型:CODE16、CODE32和DATA。TestEQU50;定义标号Test的值为50AddrEQU0x55,CODE32;定义Addr

的值为0x55,且该处为32位的ARM指令。2022/12/5嵌入式系统原理及应用刘军芳1997、EXPORT(或GLOBAL)语法格式:EXPORT标号{[WEAK]}EXPORT伪指令用于在程序中

声明一个全局的标号,该标号可在其他的文件中引用。标号在程序中区分大小写,[WEAK]选项声明其他的同名标号优先于该标号被引用。AREAInit,CODE,READONLYEXPORTStest;声明一个可全局引用的标号Stest..END2

022/12/5嵌入式系统原理及应用刘军芳2008、IMPORT(或EXTERN)语法格式:IMPORT标号{[WEAK]}IMPORT伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,而且无

论当前源文件是否引用该标号,该标号均会被加入到当前源文件的符号表中。标号在程序中区分大小写,[WEAK]选项表示当所有的源文件都没有定义这样一个标号时,编译器也不给出错误信息,在多数情况下将该标号置为0,若该标号为B或BL指令引用,则

将B或BL指令置为NOP操作。AREAInit,CODE,READONLYIMPORTMain;通知编译器当前文件要引用标号Main,但Main在其他源文件中定义..END2022/12/5嵌入式系统原理及应用刘军芳2019、EXTERN格式:EXTE

RN标号{[WERK]}该指令用于通知编译器要使用的标号在其他的元文件中定义,但要在当前源文件中引用,如果当前源文件实际并未引用该标号,该标号就不会被加入到当前源文件的符号表中。标号在程序中区分大小写,[WEAK]选项表示当前所有的源文件都没有定义这样一个标号时,便一起也不给出错信息,在多数情

况下将该标号置为0,若该标号为B或BL指令引用,则将B或BL指令置为NOP操作。实例:AREAInitCODE,READONLYEXITENMain…….END2022/12/5嵌入式系统原理及应用刘军芳20210、GET(或INCLUDE)语

法格式:GET文件名GET伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。GET伪指令只能用于包含源文件,包含目标文件需要使用INCBIN伪指令AREAInit,CODE,READONL

YGETa1.s;通知编译器当前源文件包含源文件a1.sGETC:\a2.s;通知编译器当前源文件包含源文件C:\a2.s..END2022/12/5嵌入式系统原理及应用刘军芳20311、INCBIN语法格式:INCBIN文件名

INCBIN伪指令用于将一个目标文件或数据文件包含到当前的源文件中,被包含的文件不作任何变动的存放在当前文件中,编译器从其后开始继续处理。实例:AREAInit,CODE,READONLYINCBINa1

.dat;通知编译器当前源文件包含文件a1.datINCBINC:\a2.txt;通知编译器当前源文件包含文件C:\a2.txt..END2022/12/5嵌入式系统原理及应用刘军芳20412、RN语法格式:

名称RN表达式RN伪指令用于给一个寄存器定义一个别名。采用这种方式可以方便程序员记忆该寄存器的功能。其中,名称为给寄存器定义的别名,表达式为寄存器的编码。TempRNR0;将R0定义一个别名Temp2022/12/5嵌入式系统原理及应用刘军芳205

13、ROUT格式:{}ROUT该伪指令用于给一个局部变量定义作用范围。在程序中未使用该伪指令时,局部变量的作用范围为所在的AREA,而使用了该变量后,局部变量的作用范围为当前ROUT和下一个ROUT之间。2022/12/5嵌入式系统原理及应用刘军芳206伪指令ADRADRLL

DR2022/12/5嵌入式系统原理及应用刘军芳207ADR-小范围的地址读取伪指令语法格式ADR{cond}register,exprcond:可选的指令执行条件register:目标寄存器expr:基于PC或寄存器的地址表达式,取值范围:地址非字

对齐,-255~255地址字对齐,-1020~1020将基于PC或寄存器的地址值读取到寄存器中。ADR伪指令被替换成一条合适的指令(ADD指令或SUB指令)。如果不能用一条来实现ADR伪指令的功能,编译器将报告错误。2022/12/5嵌入式系统原理及应用刘军芳208ADR

-小范围的地址读取伪指令示例:startMOVr0,#10;PC值为当前指令地址值加8字节ADRr4,start;本ADR伪指令将被编译器替换成;SUBr4,pc,#0xc2022/12/5嵌入式系统原理及应用刘军芳209ADRL-中等范围的

地址读取伪指令语法格式ADRL{cond}register,exprcond:可选的指令执行条件register:目标寄存器expr:基于PC或寄存器的地址表达式,取值范围:地址非字对齐,-64KB~64K

B地址字对齐,-256KB~256KB将基于PC或寄存器的地址值读取到寄存器中。ADRL伪指令被替换成两条合适的指令。如果不能用两条来实现ADRL伪指令的功能,编译器将报告错误。2022/12/5嵌入式系统原理及应用刘军芳210

ADRL-中等范围的地址读取伪指令示例:startMOVr0,#10;PC值为当前指令地址值加8字节ADRr4,start+60000;本ADRL伪指令将被编译器替换成下面两条指令;ADDr4,pc,#0xe800;ADDr4,r4,

#0x254;60000=0xEA602022/12/5嵌入式系统原理及应用刘军芳211LDR-大范围的地址读取伪指令语法格式LDR{cond}register,=[expr|label-expr]cond:可选的指令执行条件register:

目标寄存器expr:32位常数当expr没有超过MOV或MVN指令中的地址取值范围时,编译器用合适的MOV或MVN指令代替该LDR伪指令反之,编译器将该常数放在数据缓冲池中,同时用一条基于PC的LDR指令读取该常数。LDR伪指令处的PC值到数据缓冲池中

目标数据所在地址的偏移量要小于4KB。将32位常数或者地址值读取到寄存器中。2022/12/5嵌入式系统原理及应用刘军芳212LDR-大范围的地址读取伪指令示例1:将0xff0读取到R1中LDRR1,=0xFF0;汇编后将得到

MOVR1,#0xFF0示例2:将0xfff读取到R1中LDRR1,=0xFFF;LDRR1,[PC,OFFSET_TO_LPOOL];…;LPOOLDCD0xFFF示例3:将外部地址ADDR1读取到R1中LDRR1,=ADDR1

;LDRR1,[PC,OFFSET_TO_LPOOL];LPOOLDCDADDR12022/12/5嵌入式系统原理及应用刘军芳213ARM汇编程序中每一行的通用格式为:{标号}{指令|指示符|伪指令}{;注解}。在ARM汇编语言源程序中,除了标号和注

释外,指令、伪指令和指示符都必须有前导空格,而不能顶格书写。如果每一行的代码太长,可以使用字符“\”将其分行书写,并允许有空行。指令助记符、指示符和寄存器名既可以用大写字母,也可以用小写字母,但不能混用。注释从“;”开始,到该行结束为止。标号代表一个地址,段内标号的地址值在汇

编时确定,段外标号的地址值在链接时确定。5.2汇编语言的语句格式2022/12/5嵌入式系统原理及应用刘军芳2145.2.1ARM汇编语言程序中常用的符号在汇编语言程序设计中,经常使用各种符号代替地址、变量和常

量等,以增加程序的可读性。尽管符号的命名由编程者决定,但并不是任意的,必须遵循以下的约定:—符号区分大小写,同名的大、小写符号会被编译器认为是两个不同的符号。—符号在其作用范围内必须唯一。—自定义的符号名不能与系统的保留字相同。

—符号名不应与指令或伪指令同名。2022/12/5嵌入式系统原理及应用刘军芳2151、程序中的变量程序中的变量是指其值在程序的运行过程中可以改变的量。ARM(Thumb)汇编程序所支持的变量有数字变量、逻辑变量和字符串变量。数字变量用于在程序的运行中保

存数字值,但注意数字值的大小不应超出数字变量所能表示的范围。逻辑变量用于在程序的运行中保存逻辑值,逻辑值只有两种取值情况:真或假。字符串变量用于在程序的运行中保存一个字符串,但注意字符串的长度不应超出字符串

变量所能表示的范围。在ARM(Thumb)汇编语言程序设计中,可使用GBLA、GBLL、GBLS伪指令声明全局变量,使用LCLA、LCLL、LCLS伪指令声明局部变量,并可使用SETA、SETL和SETS对其进行初始

化。2022/12/5嵌入式系统原理及应用刘军芳2162、程序中的常量程序中的常量是指其指在程序的运行过程中不能被改变的量。ARM(Thumb)汇编程序所支持的常量有数字常量、逻辑常量和字符串常量。数字常量一般为32位的整数,当作为无符号数时,其取值范围

为0~232-1,当作为有符号数时,其取值范围为-231~231-1。逻辑常量只有两种取值情况:真或假。字符串常量为一个固定的字符串,一般用于程序运行时的信息提示。2022/12/5嵌入式系统原理及应

用刘军芳2173、程序中的变量代换程序中的变量可通过代换操作取得一个常量。代换操作符为“$”。如果在数字变量前面有一个代换操作符“$”,编译器会将该数字变量的值转换为十六进制的字符串,并将该十六进制的字符串代换“$”后的数字变量。如果在逻辑变量

前面有一个代换操作符“$”,编译器会将该逻辑变量代换为它的取值(真或假)。如果在字符串变量前面有一个代换操作符“$”,编译器会将该字符串变量的值代换“$”后的字符串变量。2022/12/5嵌入式系统原理及应用刘军芳218使用示例:LCLS

S1;定义局部字符串变量S1和S2LCLSS2S1SETS“Test!”S2SETS“Thisisa$S1”;字符串变量S2的值为“ThisisaTest!”2022/12/5嵌入式系统原理及应用刘军芳2195.2.2ARM汇编

语言中的表达式和运算符在汇编语言程序设计中,也经常使用各种表达式,表达式一般由变量、常量、运算符和括号构成。常用的表达式有数字表达式、逻辑表达式和字符串表达式,其运算次序遵循如下的优先级:—优先级相同的双目运算符的运算顺序为从左到右。—相邻的单目运算符的运算顺序为从右到

左,且单目运算符的优先级高于其他运算符。—括号运算符的优先级最高2022/12/5嵌入式系统原理及应用刘军芳220根据操作数的个数,运算符可以分为单目,双目,三目运算符,也成为一元,二元,三元运算符等。若完成一个操作需

要两个操作数,则称该运算符为双目运算符;若完成一个操作需要一个操作数,则称该运算符为单目运算符。1。单目就是这个运算符只对一个变量进行操作代表符号:!(逻辑非)~(按位取反)++(自增)--(自减)举例:inta=

1;a++;(第二句“a++”则只对a一个变量进行了操作)2。双目就是这个运算符对两个变量进行操作举例:inta=1,b=2,c;c=a+b;(第二句“c=a+b”则是对a,b两个变量进行了操作)2022/12/5嵌入式系统原理及应用刘军芳2211、数字表达式及运算符

数字表达式一般由数字常量、数字变量、数字运算符和括号构成。与数字表达式相关的运算符如下:—“+”、“-”、“×”、“/”及“MOD”算术运算符以上的算术运算符分别代表加、减、乘、除和取余数运算。例如,以X和Y表示两个数字表

达式,则:X+Y表示X与Y的和。X-Y表示X与Y的差。X×Y表示X与Y的乘积。X/Y表示X除以Y的商。X:MOD:Y表示X除以Y的余数。2022/12/5嵌入式系统原理及应用刘军芳222移位运算符—“ROL”、“ROR”、“SHL”及“SHR”移

位运算符以X和Y表示两个数字表达式,以上的移位运算符代表的运算如下:X:ROL:Y表示将X循环左移Y位。X:ROR:Y表示将X循环右移Y位。X:SHL:Y表示将X左移Y位。X:SHR:Y表示将X右移Y位。2022/12/5嵌入式系统原理及应用刘军芳223按位逻辑运算符—“A

ND”、“OR”、“NOT”及“EOR”按位逻辑运算符以X和Y表示两个数字表达式,以上的按位逻辑运算符代表的运算如下:X:AND:Y表示将X和Y按位作逻辑与的操作。X:OR:Y表示将X和Y按位作逻辑或的操作。:NOT:Y表示将Y按位作逻辑非的操作。X:EOR:Y表示将X和Y

按位作逻辑异或的操作。2022/12/5嵌入式系统原理及应用刘军芳2242、逻辑表达式及运算符逻辑表达式一般由逻辑量、逻辑运算符和括号构成,其表达式的运算结果为真或假。与逻辑表达式相关的运算符如下:—“=”、“>”、“

<”、“>=”、“<=”、“/=”、“<>”运算符以X和Y表示两个逻辑表达式,以上的运算符代表的运算如下:X=Y表示X等于Y。X>Y表示X大于Y。X<Y表示X小于Y。X>=Y表示X大于等于Y。X<=Y表示X小于等于Y。X/=Y表示X不等于Y。X

<>Y表示X不等于Y。2022/12/5嵌入式系统原理及应用刘军芳225—“LAND”、“LOR”、“LNOT”及“LEOR”运算符以X和Y表示两个逻辑表达式,以上的逻辑运算符代表的运算如下:X:LAND:Y表示将X和Y作逻辑与的操作。X

:LOR:Y表示将X和Y作逻辑或的操作。:LNOT:Y表示将Y作逻辑非的操作。X:LEOR:Y表示将X和Y作逻辑异或的操作。2022/12/5嵌入式系统原理及应用刘军芳2263、字符串表达式及运算符字符串表达式一般由

字符串常量、字符串变量、运算符和括号构成。编译器所支持的字符串最大长度为512字节。常用的与字符串表达式相关的运算符如下:—LEN运算符LEN运算符返回字符串的长度(字符数),以X表示字符串表达式,其语法格式如下::L

EN:X2022/12/5嵌入式系统原理及应用刘军芳227—CHR运算符CHR运算符将0~255之间的整数转换为一个字符,以M表示某一个整数,其语法格式如下::CHR:M—STR运算符STR运算符将一个数字表达式或逻辑表达式转换为一个字符串。对于数字表达式,STR运算符将其

转换为一个以十六进制组成的字符串;对于逻辑表达式,STR运算符将其转换为字符串T或F,其语法格式如下::STR:X其中,X为一个数字表达式或逻辑表达式。2022/12/5嵌入式系统原理及应用刘军芳228—LEFT运算符LEFT运算符返回某个字符串左端的一个子串,其语法格式如下:X:

LEFT:Y其中:X为源字符串,Y为一个整数,表示要返回的字符个数。—RIGHT运算符与LEFT运算符相对应,RIGHT运算符返回某个字符串右端的一个子串,其语法格式如下:X:RIGHT:Y其中:X为源字符串,Y为一个整数

,表示要返回的字符个数。2022/12/5嵌入式系统原理及应用刘军芳229—CC运算符CC运算符用于将两个字符串连接成一个字符串,其语法格式如下:X:CC:Y其中:X为源字符串1,Y为源字符串2,CC运算符将Y连接到X的后面。2022/12/5嵌入式系统原理及应用刘军芳

2304、与寄存器和程序计数器(PC)相关的表达式及运算符常用的与寄存器和程序计数器(PC)相关的表达式及运算符如下:—BASE运算符BASE运算符返回基于寄存器的表达式中寄存器的编号,其语法格式如下::BASE:X其中,X为

与寄存器相关的表达式。—INDEX运算符INDEX运算符返回基于寄存器的表达式中相对于其基址寄存器的偏移量,其语法格式如下::INDEX:X其中,X为与寄存器相关的表达式。2022/12/5嵌入式系统原理及应用刘军芳2315、其他常用运算符—?运算符

?运算符返回某代码行所生成的可执行代码的长度,例如:?X返回定义符号X的代码行所生成的可执行代码的字节数。—DEF运算符DEF运算符判断是否定义某个符号,例如::DEF:X如果符号X已经定义,则结

果为真,否则为假。2022/12/5嵌入式系统原理及应用刘军芳2325.3ARM汇编语言的程序结构在ARM(Thumb)汇编语言程序中,以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。段可以分为代码段和数据

段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据。一个汇编程序至少应该有一个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译链接时最终形成一个可执行的映象文件。2022/12/5嵌入式系统原理

及应用刘军芳233可执行映象文件通常由以下几部分构成:—一个或多个代码段,代码段的属性为只读。—零个或多个包含初始化数据的数据段,数据段的属性为可读写。—零个或多个不包含初始化数据的数据段,数据段的属性为可读写。链接器根据系统默认或用户设定的规则,将各个段安排在存储器中的相应位置。因此

源程序中段之间的相对位置与可执行的映象文件中段的相对位置一般不会相同。2022/12/5嵌入式系统原理及应用刘军芳234汇编语言源程序的基本结构AREAInit,CODE,READONLYENTRYStartLDRR0,=0x

3FF5000LDRR1,0xFFSTRR1,[R0]LDRR0,=0x3FF5008LDRR1,0x01STRR1,[R0]┉┉END注意:1、所有的标号必须在一行的顶格书写,其后不要添加“:”;2、所有的指令都不能顶格书写;3、对变量的设置、常量的

定义,其标识符必须在一行顶格书写;4、ARM汇编器对标识符大小写敏感(即区分大小写);5、一个ARM指令、伪指令、寄存器名可以为大写字母也可以为小写字母,但是不能大小写混合使用;6、注释使用“;”,注释的内容有“;”起到此行

结束,也可以在一行顶格书写。2022/12/5嵌入式系统原理及应用刘军芳235在汇编语言程序中,用AREA伪指令定义一个段,并说明所定义段的相关属性,本例定义一个名为Init的代码段,属性为只读。ENT

RY伪指令标识程序的入口点,接下来为指令序列,相当于C语言的main()标识,是一个代码段的入口,一个汇编语言源文件最多只能有一个ENTRY,也可以没有。START标号标识指令序列的开始。程序的末尾为END伪指令,该伪指令告诉编译器源文件的结束,每一个汇编程序段都必须有一条

END伪指令,指示代码段的结束。2022/12/5嵌入式系统原理及应用刘军芳236STARTMOVR0,#1ABC:MOVR1,#2MOVR2,#3loopMovR2,#3ADDR0,R0,R1BLoop2022/12/5嵌

入式系统原理及应用刘军芳2375.3.2ARM汇编语言中的子程序调用在ARM汇编语言程序中,子程序的调用一般是通过BL指令来实现的。在程序中,使用指令:BL子程序名该指令在执行时完成如下操作:将子

程序的返回地址存放在连接寄存器LR中,同时将程序计器PC指向子程序的入口点,当子程序执行完毕需要返回调用处时,只需要将存放在LR中的返回地址重新拷贝给程序计数器PC即可。2022/12/5嵌入式系统原理及应用刘军芳238子程序调用Lable程序A程序BR14

BLLable地址A???MOVPC,LRR14(地址A)Lable???1.程序A执行过程中调用程序B;操作流程2.程序跳转至标号Lable,执行程序B。同时硬件将“BLLable”指令的下一条指令所在地

址存入R14(LR);3.程序B执行最后,将R14寄存器的内容放入PC,返回程序A;2022/12/5嵌入式系统原理及应用刘军芳239存在的问题主程序和子程序中使用寄存器出现冲突如何解决?主程序和子程序中参数如何传递?2022/12/5嵌入式系统原理及应用刘军芳240寄存器冲突保存寄存器

的值——寄存器的值入栈保存寄存器的内容有两种办法:1、在主程序中入栈和弹出堆栈2、在子程序中入栈和弹出堆栈2022/12/5嵌入式系统原理及应用刘军芳241参数传递在调用子程序的同时,也可以完成参数的传递和从子程序回运算的结果,通常可以使用寄存器

R0~R3完成。参数多余四个怎么办?通过堆栈传递剩余参数!2022/12/5嵌入式系统原理及应用刘军芳242寄存器使用规则在调用子程序的同时,也可以完成参数的传递和从子程序回运算的结果,通常可以使用寄存器

R0~R3完成。被调用的子程序在返回前无须恢复寄存器R0~R3的内容。在子程序中,使用寄存器R4~R11来保存局部变量。在Thumb程序中,通常只能使用寄存器R4~R7来保存局部变量。寄存器R12用做过程调用中

间临时寄存器,记作IP。寄存器R13用做堆栈指针SP。在子程序中寄存器R13不能用做其它用途。寄存器SP在进入子程序时的值和退出子程序的值必须相等。寄存器R14称为链接寄存器LR,它用于保存子程序的返回地址。寄存器R15为程序计数器PC,不能用做其他用途

。2022/12/5嵌入式系统原理及应用刘军芳243子程序结果返回规则结果为一个32位的整数时,可以通过寄存器R0返回;结果为一个64位整数时,可以通过寄存器R0和R1返回,依次类推。2022/12/5嵌入式系统原理及应

用刘军芳2445.3.3ARM汇编语言与C/C++的混合编程汇编语言与C/C++的混合编程通常有以下几种方式:-在C/C++代码中嵌入汇编指令。-在汇编程序和C/C++的程序之间进行变量的互访。

-汇编程序、C/C++程序间的相互调用。2022/12/5嵌入式系统原理及应用刘军芳2451、在C语言中内嵌汇编__asm{[指令]/*注释*/______[指令]}需要特别注意的是__asm是两个下划线。2022/12/5嵌入式系统原理及应用刘军芳246在C中内嵌的汇编指令包含大部分的ARM和

Thumb指令,不过其使用与汇编文件中的指令有些不同,存在一些限制,主要有下面几个方面:a.不能直接向PC寄存器赋值,程序跳转要使用B或者BL指令.b.在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突.c.R12和R13可能被编译器用来存放

中间编译结果,计算表达式值时可能将R0到R3、R12及R14用于子程序调用,因此要避免直接使用这些物理寄存器.d.一般不要直接指定物理寄存器,而让编译器进行分配。2022/12/5嵌入式系统原理及应用刘军芳247使能IRQ中断__inlinevoide

nable_IRQ(void){inttmp;__asm{MRStmp,CPSRBICtmp,tmp,#0x80MSRCPSR_c,tmp}}2022/12/5嵌入式系统原理及应用刘军芳2482.在汇编中使用C定义的全局变量内嵌汇编不用单独编辑汇编语言文件

,比较简洁,但是有诸多限制,当汇编的代码较多时一般放在单独的汇编文件中。这时就需要在汇编和C之间进行一些数据的传递,最简便的办法就是使用全局变量。2022/12/5嵌入式系统原理及应用刘军芳249/*cfile.c*//*定义全局变量,并作为主调程序*/#include<stdio.h>

externasmDouble(void);intgVar_1=12;intmain(){}AREAasmfile,CODE,READONLYEXPORTasmDoubleasmDoubleIMPORTgVar_1ldrr0,=gVar_1……..END2022/12/5嵌入式系统

原理及应用刘军芳2503.在C中调用汇编的函数在C中调用汇编文件中的函数,要做的主要工作有两个,一是在C中声明函数原型,并加extern关键字;二是在汇编中用EXPORT导出函数名,并用该函数名作为汇编代码段的标识,最后用movpc,lr返回。然后,就可以在C中使用该

函数了。从C的角度,并不知道该函数的实现是用C还是汇编。更深的原因是因为C的函数名起到表明函数代码起始地址的作用,这个和汇编的标号是一致的。2022/12/5嵌入式系统原理及应用刘军芳251#include<stdio.h>exte

rnvoidasm_strcpy(constchar*src,char*dest);intmain(){};asmfunctionimplementationAREAasmfile,CODE,READONLYEXPORT

asm_strcpyasm_strcpy……….movpc,lrEND2022/12/5嵌入式系统原理及应用刘军芳252在一个汇编源文件中定义了如下求和函数EXPORTadd;声明add子程序将被外部函数

调用……add;求和子程序addADDr0,r0,r1MOVpc,lr……在一个C程序的main()函数中对add汇编子程序进行了调用:2022/12/5嵌入式系统原理及应用刘军芳253externintadd(intx,inty);//声明add为外部函数voidmain(){

inta=1,b=2,c;c=add(a,b);//调用add子程序……}当main()函数调用add汇编子程序时,变量a、b的值会给了r0和r1,返回结果由r0带回,并赋值给变量c。函数调用结束后,变量c的值变成3。2022/12/5嵌入式系统原理及应用刘军芳2

544.在汇编中调用C的函数在实际的编程应用中,使用较多的方式是:程序的初始化部分用汇编语言完成,然后用C/C++完成主要的编程任务,程序在执行时首先完成初始化过程,然后跳转到C/C++程序代码中,汇编程序和C/C++程序之间一般没有参数的传递,也没

有频繁的相互调用,因此,整个程序的结构显得相对简单,容易理解。2022/12/5嵌入式系统原理及应用刘军芳255在汇编中调用C的函数,需要在汇编中使用IMPORT伪指令声明将要调用的C函数名。在调用C程序时,要正确地设置

入口参数,然后使用BL调用。C的代码放在一个独立的C文件中进行编译,剩下的工作由连接器来处理。2022/12/5嵌入式系统原理及应用刘军芳256IMPORTFunc;通知编译器该标号为一个外部标号AREAInit,CODE,READONLY;定义一个代码段

ENTRY;定义程序的入口点LDRR0,=0x3FF0000;初始化系统配置寄存器LDRR1,=0xE7FFFF80STRR1,[R0]LDRSP,=0x3FE1000;初始化用户堆栈BLFunc;跳转到Func()函数处的C/C++代码执行END;标识汇编程序的结束voidFunc(v

oid){………}2022/12/5嵌入式系统原理及应用刘军芳257例如在一个C源文件中定义了如下求和函数intadd(intx,inty){return(x+y);}调用add()函数的汇编程序结构如下:IMPORTadd;声明要调用的C函数……MOVr0,1MOVr

1,2BLadd;调用C函数add……当进行函数调用时,使用r0和r1实现参数传递,返回结果由r0带回。函数调用结束后,r0的值变成3。2022/12/5嵌入式系统原理及应用刘军芳258基于ARM的C语言与汇编语言混合编程举例下面给出了一个向串口不断发送0x5

5的例子:该工程的启动代码使用汇编语言编写,向串口发送数据使用C语言实现,下面是启动代码的整体框架:2022/12/5嵌入式系统原理及应用刘军芳259……IMPORTMainAREAInit,CODE,READONLY;ENTRY……BLMain;跳转

到Main()函数处的C/C++程序……END;标识汇编程序结束2022/12/5嵌入式系统原理及应用刘军芳260下面是使用C语言编写的主函数:#include"..\inc\config.h"//将有关硬件定义的头文件包含进来uns

ignedchardata;//定义全局变量voidmain(void){Target_Init();//对目标板的硬件初始化Delay(10);//延时data=0x55;//给全局变量赋值

while(1){Uart_Printf("%x",data);//向串口送数Delay(10);}}2022/12/5嵌入式系统原理及应用刘军芳261作业:P1602、5、7、82022/12/5嵌入式系统原理及应用刘军芳2621、

写一段ARM汇编程序:循环累加队列中的所有元素,直到碰上零值元素,结果放在r4.2、写一个汇编主程序,把一个含64个带符号的16-bit数据组成的队列求平方和。2022/12/5嵌入式系统原理及应用刘军芳263

小橙橙
小橙橙
文档分享,欢迎浏览!
  • 文档 25747
  • 被下载 7
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?