版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
会计学1ARM体系结构与结构ARM指令集——跳转(分支)指令
在ARM中有两种方式可以实现程序的跳转:1、使用跳转(分支Branch)指令B或BL跳转2、直接向PC寄存器赋值实现跳转,实现在232(4GB)空间的跳转,如:movpc,r2 ;r2跳转的地址。B、BL跳转指令:跳转指令B,仅仅跳转;带返回地址的跳转指令BL,跳转同时还将BL指令的下一条指令的地址(返回地址)放入LR;第1页/共159页取指译码执行取指译码执行取指译码执行PC指针?PC-8PC-4MOVLR,PCMOVPC,#0XFF000000带返回的跳转指令BLADDR0,R1,R2跳转并执行完0XFF000000处的子程序,用MOVPC,LR
实现返回。注意:将暂时放弃ADD指令的执行。取指译码执行取指译码执行取指译码执行PC指针?PC-8PC-4使用PC实现长跳转BLLable执行BLLable
指令的同时将LR=PC-4,执行完Lable处的子程序后用MOVPC,LR
实现返回ADDR3,R0,R2第2页/共159页B、BL指令格式如下:B{L}{<cond>}<target_address> <target_address> 为指令跳转的目标地址。如:BLabelB、BL指令跳转范围限制在当前指令的±32M字节地址内(ARM指令为字对齐,最低2位地址固定为0)。跳转指令中的实际值(signed_immed_24)是相对PC值的一个偏移量;它的值由汇编器来计算,它是24位有符号数,左移两位后(去掉一位符号位后,有效偏移为25位(+/-32M)),由符号扩展到32位。cond101Lsigned-immed_24B及BL指令的编码格式023242726253128第3页/共159页BLLabelxxxxxxLabelxxxMOVPC,LRAddr1Addr2xxxxxxLRPCARM指令——分支指令BL指令格式如下:BL{cond}Label ;PC←label,LR←PC-4
带返回地址的BL指令,适用于子程序调用,使用该指令后,下一条指令的地址拷贝到R14(即LR)寄存器中,然后跳转到指定地址运行程序。LabelAddr2Addr21.当程序执行到BL跳转指令时,硬件将下一条指令的地址Addr2装入LR寄存器,并把跳转地址装入程序计数器(PC)2.程序跳转到目标地址Label继续执行,当子程序执行结束后,将LR寄存器内容存入PC,返回调用函数继续执行第4页/共159页3.2指令集介绍ARM指令集——ARM数据处理指令数据处理指令大致可分为4类:数据传送指令: MOV MVN;算术运算指令: ADD ADC SUB SBC RSB RSC;逻辑运算指令: AND ORR EOR BIC;比较指令: CMP CMN TST TEQ。数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。数据处理指令中除比较指令外均可选择使用S后缀,并影响cpsr状态标志。
第5页/共159页3.2指令集介绍ARM指令集——ARM数据处理指令数据处理指令大致可分为4类:数据传送指令: MOV MVN;算术运算指令: ADD ADC SUB SBC RSB RSC;逻辑运算指令: AND ORR EOR BIC;比较指令: CMP CMN TST TEQ。数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。数据处理指令中除比较指令外均可选择使用S后缀,并影响状态标志。
第6页/共159页ARM数据处理指令——数据传送MOV指令格式如下:
MOV{cond}{S}Rd,operand2;Rd←operand2
MOV指令将立即数(合法)或寄存器传送到目标寄存器(Rd),可用于移位运算等操作。MOV指令举例如下:
MOV R1,#0x10
;R1=0x10
MOV R0,R1
;R0=R1
MOVR2,R2,LSL#2
MOVSPC,LR
;PC为目标寄存器时,PC=LR,同时spsr--〉cpsr,本条指令只能在异常模式下使用,因为用户和系统模式没有spsr。第7页/共159页ARM数据处理指令——数据传送MVN指令格式如下:
MVN
{cond}{S}Rd,operand2;Rd←(~operand2)MVN指令将立即数或寄存器按位取反后传送到目标寄存器(Rd),operand2为一个合法立即数,因为其具有取反功能,所以可以装载范围更广的立即数。
MVN指令举例如下:
MVN R1,#0xFF
;R1=0xFFFFFF00
MVN R1,R2
;将R2取反,结果存到R1 MVNR2,#0 ;将-1放入R2第8页/共159页3.2指令集介绍ARM指令集——ARM数据处理指令数据处理指令大致可分为4类:数据传送指令: MOV MVN;算术运算指令: ADD ADC SUB SBC RSB RSC;逻辑运算指令: AND ORR EOR BIC;比较指令: CMP CMN TST TEQ。数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。数据处理指令中除比较指令外均可选择使用S后缀,并影响状态标志。第9页/共159页ADD(addition加)指令格式如下:
ADD{cond}{S}Rd,Rn,operand2;Rd←Rn+operand2
加法运算指令——ADD将operand2的值与Rn的值相加,结果保存到Rd寄存器,operand2为立即数时,必须为合法立即数。应用示例:ADDSR1,R1,#1 ;R1=R1+1,并影响标志位
ADDR1,R1,R2 ;R1=R1+R2
第10页/共159页ARM数据处理指令——算术运算ADC指令格式如下:ADC{cond}{S}Rd,Rn,operand2;Rd←Rn+operand2+Carry
带进位加法指令——ADC将operand2的值与Rn的值相加,再加上CPSR中的C标志位,结果保存到Rd寄存器。应用示例(使用ADC实现64位加法,结果存于R1、R0中):
ADDSR0,R0,R2 ;R0等于低32位相加,并影响标志位
ADCR1,R1,R3
;R1等于高32位相加,并加上低32位进位C第11页/共159页SUB(subtract减)指令格式如下:SUB{cond}{S}Rd,Rn,operand2;Rd←Rn-operand2
减法运算指令——SUB指令用寄存器Rn减去operand2,结果保存到Rd中。应用示例:
SUB R0,R0,#1
;R0=R0-1,不影响标志位
SUBS R2,R1,R2
;R2=R1-R2,并影响标志位第12页/共159页SBC指令格式如下:SBC{cond}{S}Rd,Rn,operand2
;Rd←Rn-operand2-(非)Carry带进位减法指令——SBC用寄存器Rn减去operand2,再减去CPSR中的C标志位的非(减法中产生借位时C位=0),结果保存到Rd中。应用示例(使用SBC实现64位减法,结果存于R1、R0中):SUBSR0,R0,R2;低32位相减,并影响标志位SBCR1,R1,R3;高32位相减,并减去低位借位C的 ;反码第13页/共159页ARM数据处理指令——算术运算RSB(ReverseSubtract)指令格式如下:
RSB{cond}{S}Rd,Rn,operand2;Rd←operand2-Rn
逆向减法运算指令——RSB指令将operand2的值减去Rn,结果保存到Rd中。应用示例:
RSBR3,R1,#0xFF00 ;R3=0xFF00-R1RSBSR1,R2,R2,LSL#2 ;R1=(R2<<2)-R2=R2×3
第14页/共159页RSC指令格式如下:RSC{cond}{S}Rd,Rn,operand2;Rd←operand2-Rn-(NOT)Carry
带进位逆向减法指令——RSC指令用寄存器operand2减去Rn,再减去CPSR中的C位的非(减法中产生借位时C位=0),结果保存到Rd中。
应用示例(使用RSC指令实现求64位数值的负数):
RSBSR2,R0,#0RSCR3,R1,#0第15页/共159页3.2指令集介绍ARM指令集——ARM数据处理指令数据处理指令大致可分为4类:数据传送指令: MOV MVN;算术运算指令: ADD ADC SUB SBC RSB RSC;逻辑运算指令:
AND ORR EOR BIC;比较指令: CMP CMN TST TEQ。数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。数据处理指令中除比较指令外均可选择使用S后缀,并影响状态标志。第16页/共159页AND指令格式如下:AND{cond}{S}Rd,Rn,operand2;Rd←Rn&operand2(&为与运算符)逻辑与操作指令——AND指令将operand2的值与寄存器Rn的值按位作逻辑“与”操作,结果保存到Rd中。应用示例:ANDSR0,R0,#0x01;R0=R0&0x01,取出最低位数据。;影响标志位ANDR2,R1,R3 ;R2=R1&R3
第17页/共159页ORR指令格式如下:ORR{cond}{S}Rd,Rn,operand2;Rd←Rn|operand2
(|为或运算符)逻辑或操作指令——ORR指令将operand2的值与寄存器Rn的值按位作逻辑“或”操作,结果保存到Rd中。应用示例:
ORRR0,R0,#0x0F
;将R0的低4位置1
MOV R1,R2,LSR#24
ORR R3,R1,R3,LSL#8
;使用ORR指令将R2的高8位数据移入到R3低8位中第18页/共159页ARM数据处理指令——逻辑运算指令EOR指令格式如下:
EOR{cond}{S}Rd,Rn,operand2;Rd←Rn^operand2(^为异或运算符)逻辑异或操作指令——EOR指令将operand2的值与寄存器Rn的值按位作逻辑“异或”操作(不相同的位为1,相同的位为0),结果保存到Rd中。应用示例:
EOR R1,R1,#0x0F
;将R1的低4位取反
EORR2,R1,R0 ;R2=R1^R0
EORS R0,R5,#0x01;将R5和0x01进行逻辑异或,
;结果保存到R0,并影响标志位第19页/共159页ARM数据处理指令——逻辑运算指令BIC(BitClear)指令格式如下:
BIC{cond}{S}Rd,Rn,operand2;Rd←Rn&(~operand2)位清除指令——BIC指令将寄存器Rn的值与operand2的值的反码按位作逻辑“与”操作,结果保存到Rd中。应用示例:
BICR1,R1,#0x0F
;将R1的低4位清零,其它位不变
BICR1,R2,R3
;将R3的反码和R2相逻辑“与”,
;结果保存到R1中,实际上将R2中 ;与R3中为1的位号处清零第20页/共159页ARM数据处理指令——比较指令CMP(Compare)指令格式如下:
CMP{cond}Rn,operand2 ;Rn-operand2标志N、Z、C、V
比较指令——CMP指令将寄存器Rn的值减去operand2的值,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。应用示例:
CMP R1,#10
;R1与10比较,设置相关标志位
CMP R1,R2 ;R1与R2比较,设置相关标志位注意:CMP指令与SUBS指令的区别在于CMP指令不保存运算结果。第21页/共159页ARM数据处理指令——比较取反指令CMN(CompareNegative)指令格式如下:
CMN{cond}Rn,operand2 ;Rn+operand2标志N、Z、C、V负数比较指令——CMN指令使用寄存器Rn的值加上operand2的值,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。应用示例:
CMN R0,#1;R0+1(或R0-(-1)),影响条件标志位注意:CMN指令与ADDS指令的区别在于CMN指令不保存运算结果。CMN指令可用于负数比较:比如CMNR0,#1指令则表示R0与-1比较。第22页/共159页ARM数据处理指令——位测试指令TST(test)指令格式如下:
TST{cond}Rn,operand2 ;Rn&operand2影响标志N、Z、C位测试指令——TST指令将寄存器Rn的值与operand2的值按位作逻辑“与”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。应用示例:
TST R0,#0x01 ;判断R0的最低位是否为0TST R1,#0x0F ;判断R1的低4位是否为0注意:TST指令与ANDS指令的区别在于TST指令不保存运算结果。TST指令通常与EQ、NE条件码配合使用,当所有测试位均为0时,EQ有效(Z=1),而只要有一个测试位不为0,则NE有效(Z=0)。
第23页/共159页ARM数据处理指令——比较指令TEQ(TestEqual)指令格式如下:TEQ{cond}Rn,operand2 ;Rn^operand2,影响标志N、Z、C、V
相等测试指令——TEQ指令将寄存器Rn的值与operand2的值按位作逻辑“异或”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。应用示例:
TEQR0,R1 ;比较R0与R1是否相等注意:TEQ指令与EORS指令的区别在于TEQ指令不保存运算结果。使用TEQ进行相等测试时,常与EQ、NE条件码配合使用。当两个数据相等时,EQ有效(Z=1);否则NE有效(Z=0)。
第24页/共159页ARM指令小节目录1.指令格式2.条件码3.存储器访问指令4.数据处理指令5.乘法指令6.ARM分支指令7.协处理器指令8.杂项指令9.伪指令第25页/共159页ARM指令集——乘法指令 ARM微处理器支持的乘法指令与乘加指令共有6条,可分为运算结果为32位和运算结果为64位的两类。32×32位乘法/乘加指令;32×32位结果为64位的乘/乘加指令。 与前面的数据处理指令不同,指令中的所有操作数、目的寄存器必须为通用寄存器,操作数不能使用立即数或被移位的寄存器。第26页/共159页ARM指令——乘法指令MUL指令格式如下:MUL{cond}{S}Rd,Rm,Rs;Rd←Rm*Rs(Rd≠Rm)32位乘法指令——MUL(Multiply)指令将Rm和Rs中的值相乘,结果的低32位保存到Rd中。应用示例:
MULR1,R2,R3
;R1=R2×R3低32位
;R2=0x00FFFFFF,R3=0x00123456,R1=0x55EDCBAA
;0x00FFFFFF*0x00123456=123455EDCBAAMULSR0,R3,R7
;R0=R3×R7,同时影响标志位第27页/共159页ARM指令——乘法指令MLA指令格式如下:MLA{cond}{S}Rd,Rm,Rs,Rn;Rd←Rm*Rs+Rn(Rd≠Rm)32位乘加指令——MLA(MultiplyAccumulate)指令将Rm和Rs中的值相乘,再将乘积加上第3个操作数,结果的低32位保存到Rd中。应用示例:
MLA R0,R1,R2,R3
;R0=(R1×R2+R3)低32位
MLASR0,R1,R2,R3
;R0=(R1×R2+R3)低32位,同时设置CPSR中的相关条件标志位第28页/共159页ARM指令——乘法指令UMULL指令格式如下:UMULL{cond}{S}RdLo,RdHi,Rm,Rs;(RdLo,RdHi)←Rm*Rs
64位无符号乘法指令——UMULL(UnsignedMultiplylong)指令将Rm和Rs中的值作无符号数相乘,结果的低32位保存到RdLo中,而高32位保存到RdHi中。应用示例:
UMULLR0,R1,R5,R8;(R1、R0)=R5×R8
;R0=(R5×R8)的低32位 ;R1=(R5×R8)的高32位第29页/共159页ARM指令——乘法指令UMLAL指令格式如下:
UMLAL{cond}{S}RdLo,RdHi,Rm,Rs ;(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)64位无符号乘加指令——UMLAL(UnsignedMultiplyAccumulateLong)指令将Rm和Rs中的值作无符号数相乘,64位乘积与RdHi、RdLo相加,结果的低32位保存到RdLo中,而高32位保存到RdHi中。应用示例:
UMLALR0,R1,R5,R8
;(R1、R0)=R5×R8+(R1、R0)
;R0=(R5×R8)的低32位+R0
;R1=(R5×R8)的高32位+R1第30页/共159页ARM指令——乘法指令SMULL指令格式如下:SMULL{cond}{S}RdLo,RdHi,Rm,Rs;(RdLo,RdHi)←Rm*Rs64位有符号乘法指令——SMULL(SignedMultiplyLong)指令将Rm和Rs中的值作有符号数相乘,结果的低32位保存到RdLo中,而高32位保存到RdHi中。应用示例:
SMULL R2,R3,R7,R6
;(R3、R2)=R7×R6第31页/共159页ARM指令——乘法指令SMLAL指令格式如下:SMLAL{cond}{S}RdLo,RdHi,Rm,Rs;(RdLo,RdHi)←Rm*Rs+(RdLo,RdHi)
64位有符号乘加指令——SMLAL(SignedMultiplyAccumulateLong)指令将Rm和Rs中的值作有符号数相乘,64位乘积与RdHi、RdLo相加,结果的低32位保存到RdLo中,而高32位保存到RdHi中。应用示例:
SMLAL R2,R3,R7,R6
;(R3、R2)=R7×R6+(R3、R2)
第32页/共159页杂类的算术指令ARMV5及以上版本有一条指令CLZ(countleftzeros)
该指令用于计算最高位与第一个“1”之间的“0”的个数。用于以下两种场合:1、使操作数规范化(使其最高为1)时,计算需要左移的位数。2、确定优先级掩码中的最高位CLZR1,R2;把R2中第一个“1”前面的“0”的个数放入R1MOVR2,R2,LSLR1;把R2左移R1位,使R2的bit[31]=1第33页/共159页程序状态寄存器访问指令(MRS/MSR)ARM中有两条指令用于在程序状态寄存器(CPSR/SPSR)和通用寄存器(R0-R15)之间传送数据。 只有程序状态寄存器访问指令(MRS/MSR)才可以对状态寄存器CPSR和SPSR进行读/写操作。第34页/共159页寄存器类别寄存器在汇编中的名称各模式下实际访问的寄存器用户系统管理中止未定义中断快中断通用寄存器和程序计数器R0(a1)R0R1(a2)R1R2(a3)R2R3(a4)R3R4(v1)R4R5(v2)R5R6(v3)R6R7(v4)R7R8(v5)R8R8_fiqR9(SB,v6)R9R9_fiqR10(SL,v7)R10R10_fiqR11(FP,v8)R11R11_fiqR12(IP)R12R12_fiqR13(SP)R13R13_svcR13_abtR13_undR13_irqR13_fiqR14(LR)R14R14_svcR14_abtR14_undR14_irqR14_fiqR15(PC)R15状态寄存器CPSRCPSRSPSR无SPSR_abtSPSR_abtSPSR_undSPSR_irqSPSR_fiq程序状态寄存器CPSR
CPSR(CurrentProgramStatusRegister)当前程序状态寄存器
SPSR(SavedProgramStatusRegister)程序状态保存寄存器
每种异常都有自己的SPSR(由于用户模式和系统模式不是异常模式,所以它们没有SPSR),当异常发生时SPSR保存CPSR的当前值,异常退出时可通过SPSR恢复CPSR。第35页/共159页1.6程序状态寄存器简介ARM内核包含1个CPSR和5个供异常处理程序使用的SPSR。CPSR反映了当前处理器的状态,其包含:4个条件代码标志(符号(N)、零(Z)、进位(C)和溢出(V));2个中断禁止位(F/I),分别控制一种类型的中断;5个对当前处理器模式进行编码的位M[4:0];1个用于指示当前执行指令(ARM还是Thumb)的T位。第36页/共159页NZCVQ—IM0M1M2M3M4TF—...3130292827268765432101.6程序状态寄存器简介条件代码标志保留控制位溢出标志进位或借位扩展零符号标志位IRQ禁止FIQ禁止状态位模式位NZCVIM0M1M2M3M4TFCPSR寄存器的格式第37页/共159页程序状态寄存器访问指令(MRS/MSR)读CPSR可以了解当前处理器(无论出于何种模式下)的工作状态,。读SPSR寄存器可以了解进入异常前的处理器状态CPSR。
以上两条可以通过,MRS指令把cpsr/spsr读入通用寄存器(r0-r15)。对CPSR或SPSR寄存器的写操作,可以切换处理器模式、或者允许/禁止IRQ/FIQ中断等。
上面一条可以通过,MSR指令把通用寄存器(r0-r15)或立即数的值,写入cpsr/spsr。注意:不能通过写状态寄存器来改变处理器的状态(ARM态/Thumb态),只能通过带状态切换的分支指令BX来改变。第38页/共159页程序状态寄存器读指令---MRS
在ARM处理器中,只有MRS指令可以对状态寄存器CPSR和SPSR进行读操作。MRS{cond}Rd,psrMRS指令格式指令对应编码指令执行的条件码目标寄存器,不能为R15区别CPSR(为0)和SPSR(为1)寄存器
应用示例:
MRSR1,CPSR ;将CPSR状态寄存器读取到R1中第39页/共159页ARM杂项指令——状态寄存器写指令
在ARM处理器中,只有MSR指令可以对状态寄存器CPSR和SPSR进行写操作。与MRS配合使用,可以实现对CPSR或SPSR寄存器的读-修改-写操作,可以切换处理器模式、或者允许/禁止IRQ/FIQ中断等。MSR{cond}psr_fields,#immed_8rMSR指令格式1MSR{cond}psr_fields,RmMSR指令格式2指令执行的条件码CPSR或SPSR指定传送的区域,可以为以下字母(必须小写)的一个或者多个组合:c控制域(psr[7..0])x扩展域(psr[15..8])s状态域(psr[23..16])f标志域(psr[31..24])要传送到cpsr/spsr的源寄存器要传送到cpsr/spsr的(合法)立即数第40页/共159页保存要传送到状态寄存器指定域数据的源寄存器ARM杂项指令——状态寄存器写指令
在ARM处理器中,只有MSR指令可以对状态寄存器CPSR和SPSR进行写操作。与MRS配合使用,可以实现对CPSR或SPSR寄存器的读-修改-写操作,可以切换处理器模式、或者允许/禁止IRQ/FIQ中断等。指令执行的条件码CPSR(r=0)或SPSR(r=1)指定传送的区域,可以为以下字母(必须小写)的一个或者组合:c控制域(psr[7..0])x扩展域(psr[15..8])s状态域(psr[23..16])f标志域(psr[31..24])要传送到cpsr/spsr的寄存器MSR指令1编码MSR指令2编码Rotate:X2后为移位位数8_bit_immediate:8位合法立即数第41页/共159页(1)(2)(3)(4)ARM杂项指令——状态寄存器写指令
在ARM处理器中,只有MSR指令可以对状态寄存器CPSR和SPSR进行写操作。与MRS配合使用,可以实现对CPSR或SPSR寄存器的读-修改-写操作,可以切换处理器模式、或者允许/禁止IRQ/FIQ中断等。
应用示例1:;子程序:使能IRQ中断ENABLE_IRQMRSR0,CPSRBICR0,R0,#0x80MSRCPSR_c,R0MOVPC,LR
应用示例2:;子程序:禁能IRQ中断DISABLE_IRQMRSR0CPSRORRR0,R0,#0x80MSRCPSR_c,R0MOVPC,LR
1.将CPSR寄存器内容读到R0;2.修改对应于CPSR中的I控制位;3.将修改后的值写回
CPSR寄存器的对应控制域;4.返回上一层函数;第42页/共159页ARM指令集——存储器访问指令
包括:
单寄存器操作指令:LDR/STRSWP
多寄存器操作指令:LDM/STM第43页/共159页Load指令用于从存储器(包括内存和外存)中读取数据放入寄存器中。
LDRR1,[R2,R5]!
;R1
[R2+R5],R2←R2+R5, ;R2+R5的内容为地址,
[R2+R5]为该地址处的数据
Store指令用于将寄存器的数据保存到存储器。
STRR1,[R2,R5]!
;R1[R2+R5],R2←R2+R5 ;R2+R5的内容为地址,
[R2+R5]为该地址处的数据各种类型的Load/Store指令的寻址方式由两部分组成:
1〉基址寄存器:一般使用通用寄存器
2〉地址偏移量:立即数、寄存器、寄存器及一个移位常数
需要的地址=基址寄存器+地址偏移量 偏移量的形式如下页:第44页/共159页地址偏移量有以下3种格式:立即数。如:LDRR1,[R0,#0x12]
寄存器。如:LDRR1,[R0,R2]
寄存器及移位常数。如:LDRR1,[R0,R2,LSL#2]
第45页/共159页
LDR和STR指令应用示例:(1)LDR R0,[R1] ;R0[R1](2)LDR R0,[R1,R2]
(3)LDR R0,[R1,#8]
(4)LDR R0,[R1,R2]!
(5)LDR R0,[R1,#8]! (6)LDR R0,[R1,R2,LSL#2]!(7)LDR R0,[R1],R2
(8)LDR R0,[R1],R2,LSL#2(9)STRR0,[R1,#0XC];R0[R1+0XC](10)STRR0,[R1],#8;R0[R1],R1=R1+8第46页/共159页
用于将存储器中的一个字节或半字数据传送到寄存器。常用的加载指令如下:
LDRB
字节数据加载指令
LDRH
半字数据加载指令
LDRSB
有符号字节数据加载指令
LDRSH
有符号半字数据加载指令
Byte Half Sign3.2指令集介绍第47页/共159页LDRB指令的格式为:
LDR{<cond>}BRd,<存储器地址> LDRB用于从存储器中将一个8位的字节数据传送到目的寄存器Rd中,同时将寄存器的高24位清零。LDRBR0,[R1];将内存单元[R1]中的字节放入R0中,R0中高24位设置成0LDRSB指令的格式为:
LDR{<cond>}SBRd,<存储器地址> LDRSB指令用于从存储器中将一个8位的有符号字节数据传送到目的寄存器中,同时用符号位扩展到32位。LDRSBR0,[R1];将内存单元[R1]中的字节放入R0中,R0中高24位设置成符号位第48页/共159页LDRH指令的格式为:
LDR{条件}H目的寄存器,<存储器地址>LDRH用于从存储器中将一个16位的半字数据传送到目的寄存器中,同时将寄存器的高16位清零。LDRHR0,[R1];将内存单元[R1]中的半字放入R0中,R0中高16位设置成0LDRSH指令的格式为:
LDR{条件}SH目的寄存器,<存储器地址>LDRSH指令用于从存储器中将一个16位的有符号半字数据传送到目的寄存器中,同时用符号位扩展到32位。LDRHR0,[R1];将内存单元[R1]中的半字放入R0中,R0中高16位设置成符号位注意:半字读写的指定地址必须为偶数,否则将产生不可靠的结果第49页/共159页
用于将寄存器中的一个字节或半字数据传送到存储器。常用的存储指令如下
STRB
字节数据存储指令
STRH
半字数据存储指令
STRBR5,[SP,R3] ;R5的最低字节→[SP+R3] STRHR5,[SP,R3] ;R5的最低半字→[SP+R3]
3.2指令集介绍ARM存储器访问指令——单寄存器存储第50页/共159页STRB指令的格式为:
STR{条件}B源寄存器,<存储器地址>STRB指令用于从源寄存器中将一个8位的字节数据传送到存储器中。该字节数据为源寄存器中的低8位。STRB指令应用示例:
STRBR0,[R1]
;将寄存器R0中的低字节数据写入以R1为 ;地址的存储器中
STRBR0,[R1,#8] ;将寄存器R0中的低字节数据写入 ;以R1+8为地址的存储器中ARM存储器访问指令——单寄存器操作指令第51页/共159页STRH指令的格式为:
STR{条件}H源寄存器,<存储器地址> STRH指令用于从源寄存器中将一个16位的半字数据传送到存储器中。该半字数据为源寄存器中的低16位。STRH指令应用示例:
STRHR0,[R1]
;将寄存器R0中的半字数据写入以
R1为地址的存储器中
STRHR0,[R1,#8] ;将寄存器R0中的半字数据写入以
R1+8为地址的存储器中ARM存储器访问指令——单寄存器操作指令第52页/共159页 LDRT、STRT、STRBT
带后缀T,表示在特权模式(除用户模式外)下使用这类指令时,将视为一般的用户模式下的操作(权限降低),操作的为用户模式下的寄存器。第53页/共159页ARM存储器访问指令——多寄存器存取
多寄存器加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。LDM为加载多个寄存器;STM为存储多个寄存器。允许一条指令传送16个寄存器的任何子集或所有寄存器。它们主要用于现场保护、数据复制、常数传递等。常用的加载存储指令如下:
LDM
批量数据加载指令
STM
批量数据存储指令第54页/共159页ARM存储器访问指令——多寄存器存取
多寄存器加载/存储指令格式如下:LDM{cond}<模式>Rn{!},<reglist>{^}STM{cond}<模式>Rn{!},<reglist>{^}cond:指令执行的条件;模式:控制地址的增长方式,一共有8种模式;(4种堆栈:FD、ED、EA、FA,4种数据块:IA、IB、DA、DB)!:表示在操作结束后,将最后的地址写回基址寄存器Rn中;reglist
:表示寄存器列表,可以包含多个寄存器,它们使用“,”隔开,如{R1,R2,R6-R9},寄存器由小到大排列;^:该后缀不允许在用户模式或系统模式下使用。加入该后缀后,寄存器列表不包含PC时,加载/存储的寄存器是用户模式下的寄存器,而不是当前某个异常模式的寄存器。若在LDM指令且寄存器列表中包含有PC时使用,那么除了正常的多寄存器传送外,还将SPSR也拷贝到CPSR中,这可用于异常处理返回。第55页/共159页LDM(1)例LDMIAR0!,{R5-R8};R0为基址寄存器,将R0到(R0+12)地址单元的内容(4个字)放入R5-R8四个寄存器中,执行后R0=R0+16LDM(2)例LDMIAR0,{R5-R8}^;寄存器列表中不能含有PC,^后缀将强制传送用户模式下的寄存器块,而不管程序运行在哪种模式,执行后R0不变LDM(3)例LDMIASP!,{R12,R15}^;寄存器列表中必须含有PC,加载PC(跳转),同时SPSR传送到CPSR,执行后SP=SP+8STM(1)例STMIAR3!,{R6,R8,R9};将R6,R8,R9保存到R3,R3+4,R3+8地址单元中,执行后R3=R3+12STM(2)例STMIAR3!,{R6,R8,R9}^;表示在特权模式下使用用户模式下的寄存器,执行后R3=R3+12注意:1、基址寄存器不要出现在寄存器列表中,否则执行结果不可预知
2、带^不能在用户模式和系统模式下使用第56页/共159页错误的例子:LDMIAR0!,{R0,R5-R8};错误,在基址寄存器需要更新时,寄存器列表中不应含有基址寄存器LDMDBR4!,{R0,R1,R2,R3};错误,应使用省略R0-R3STMIBR15!,{R1-R3};错误,R15作为基址寄存器将产生不可预知的结果。第57页/共159页ARM存储器访问指令——寄存器和存储器交换指令SWP(Swap) 字数据交换指令
SWPB
字节数据交换指令指令格式如下:
SWP{cond}{B}Rd,Rm,[Rn]SWP指令用于将一个内存单元的内容放到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该内存单元中。SWP指令把读取和存入操作组合在一条指令中,而且2种传送不能被分开(原子操作)。其中:B为可选后缀,若有B,则交换字节,否则交换32位的字;Rd用于保存从存储器中读入的数据;Rm的数据用于存储到存储器中,若Rd与Rm相同,则为寄存器与存储器内容进行交换;Rn为要进行数据交换的存储器地址,Rn不能与Rd和Rm相同。第58页/共159页SWP/SWPB指令举例:SWPR1,R2,[R3];将内存单元[R3]中的字数据读取到R1寄存器中,同时将R2寄存器的内容放入[R3]SWPR1,R1,[R2];将R1寄存器内容和内存单元[R2]的内容互换SWPBR1,R2,[R3];将[R3]中的字节放入R1,R1的高24位设置为0,同时将R2的最低字节放入[R3]第59页/共159页3.2指令集介绍ARM指令集——异常中断产生指令如下所示:异常产生指令(软中断指令): SWI(softwareinterrupt)
断点中断指令:BKPT(BreakPoint)第60页/共159页SWI(SoftwareInterrupt)
SWI指令用于产生软中断(进入管理模式SVC),以便用户程序能调用操作系统的系统例程,操作系统在SWI的异常处理程序中提供相应的系统服务。(99页伪代码)SWI{cond} immed_24SWI指令格式SWI指令编码指令执行的条件码指令传递的参数(24位立即数)第61页/共159页
根据SWI指令传递的参数,SWI异常处理程序可以作出相应的处理。SWI指令传递参数有以下两种方法,指令中的24位立即数指定了用户请求的服务类型,参数通过通用寄存器传递。MOVR0,#0X18LDRR1,=0X20026 ;为软中断调用准备参数SWI0X123456
指令中的24位立即数被忽略,用户请求的功能号由寄存器R0的值决定。MOVR0,#12
;调用12号软中断SWI0
;为0时,不指明功能号,由R0指明功能类型第62页/共159页
在SWI异常中断处理程序中,取出SWI指令中立即数的步骤为:首先确定引起软中断的SWI指令是ARM指令还是Thumb指令,这可通过对SPSR访问得到;然后取得该SWI指令的地址,这可通过访问LR寄存器得到;接着读出该SWI指令,分解出立即数。
SWI0xXXXXXX,XX ...SWI_HandlerSTMFDSP!,{R0-R3,R12,LR} ;现场保护
MRSR0,SPSR ;读取SPSRSTMFDSP!,{R0} ;保存SPSRTSTR0,#0x20 ;测试cpsr中的T标志位、是arm?还是Thumb?
LDRNEHR0,[LR,#-2] ;若Z=0,是Thumb指令,读取指令码(16位)BICNER0,R0,#0xFF00 ;取得Thumb指令的8位立即数
LDREQR0,[LR,#-4] ;若Z=1,是ARM指令,读取指令码(32位)BICEQR0,R0,#0xFF000000 ;取得ARM指令的24位立即数
...LDMFDSP!,{R0-R3,R12,PC}^ ;SWI异常中断返回第63页/共159页
断点中断指令:BKPT(BreakPoint) 用于产生软件中断V5或V5版本以上才支持该指令,在指令代码中插入该指令,可以用于调试中设置断点。第64页/共159页
ARM作为32位处理器,虽然能进行长乘法和乘加等运算,但没有除法和更复杂的运算指令。因此,ARM作复杂的运算比较困难,比如浮点运算。但ARM可以外接协处理器,并有专门的指令来实现对协处理器的操作。
协处理器是专门用于进行辅助运算的芯片,其本身除了运算功能外没有其他功能(CP15除外),因此不能单独工作,必须和CPU一起工作。协处理器可以在片外连接,但在一些运算功能强大的微处理器也有内置的。协处理器Coprocessor第65页/共159页
ARM支持16个协处理器。在程序执行过程中,每个协处理器忽略属于ARM处理器和其他处理器的指令。当一个协处理器器不能执行属于它的协处理器指令时,将产生未定义指令异常中断,在该异常中断中,可以通过软件模拟该硬件操作。 比如,如果系统不包含向量浮点运算器,则可以选择浮点运算软件模拟包来支持向量浮点运算。协处理器Coprocessor第66页/共159页3.2指令集介绍ARM指令集——协处理器指令
协处理器指令主要用于在ARM处理器的寄存器和协处理器的寄存器之间传送数据,和在ARM协处理器的寄存器和存储器之间传送数据。ARM协处理器指令包括以下5条:CDP (CoprocessorDataProcessing)协处理器数据操作指令LDC
协处理器数据加载指令STC
协处理器数据存储指令MCR
ARM处理器寄存器到协处理器寄存器的数据传送指令MRC
协处理器寄存器到ARM处理器寄存器的数据传送指令第67页/共159页ARM协处理器指令——数据操作指令ARM处理器通过CDP指令通知ARM协处理器执行特定的操作。该操作由协处理器完成。若协处理器不能成功地执行该操作,将产生未定义指令异常中断。指令格式如下:指令执行的条件码协处理器的特定操作码协处理器的第1个源操作数寄存器协处理器的目标寄存器指令操作的协处理器名可选的协处理器特定操作码协处理器的第2个源操作数寄存器CDP{cond}coproc,opcode1,CRd,CRn,CRm{,opcode2}数据操作指令编码第68页/共159页ARM协处理器指令——数据操作指令CDP{cond}coproc,opcode1,CRd,CRn,CRm{,opcode2}
应用示例:CDPp7,2,c0,c2,c3,0;对协处理器7操作,操作码1为2,可选的操作码2为0,目标寄存器为c0,源操作数寄存器为c2,c3。第69页/共159页ARM协处理器指令——数据存取指令
协处理器数据存取指令LDC/STC指令可以将某一连续内存单元的数据读取到协处理器的寄存器中,或者将协处理器的寄存器数据写入到某一连续的内存单元中,传送的字数由协处理器来控制。若协处理器不能成功地执行该操作,将产生未定义指令异常中断。数据操作指令编码指令执行的条件码P表示前/后变址U表示加/减W表示回写N表示浮点数/整数L表示该指令是读取(为0)还是写入(为1)8位立即数偏移协处理器编号协处理器中的目标寄存器基址寄存器第70页/共159页ARM协处理器指令——数据存取指令
应用示例:
LDCp5,c2,[R2,#4];读取R2+4指向的内存单元的数据,;传送到协处理器p5的c2寄存器中
STCp5,c1,[R0,#8]!;将协处理器p5的C1寄存器内数据;传送到R0+8指向的内存单元,指令执行后R0=R0+8第71页/共159页ARM协处理器指令——寄存器传送指令
如果需要在ARM处理器中的寄存器与协处理器中的寄存器之间进行数据传送,那么可以使用MCR/MRC指令。MCR指令用于将ARM处理器的寄存器中的数据传送到协处理器的寄存器。MRC指令用于将协处理器的寄存器中的数据传送到ARM处理器的寄存器中。若协处理器不能成功地执行该操作,将产生未定义指令异常中断。MCR{cond}coproc,opcode1,Rd,CRn,CRm{,opcode2}MRC指令格式(协处理器ARM
)MCR指令格式(ARM协处理器)MRC{cond}coproc,opcode1,Rd,CRn,CRm{,opcode2}第72页/共159页ARM协处理器指令——寄存器传送指令
如果需要在ARM处理器中的寄存器与协处理器中的寄存器之间进行数据传送,那么可以使用MCR/MRC指令。MCR指令用于将ARM处理器的寄存器中的数据传送到协处理器的寄存器。MRC指令用于将协处理器的寄存器中的数据传送到ARM处理器的寄存器中。若协处理器不能成功地执行该操作,将产生未定义指令异常中断。寄存器传送指令编码指令执行的条件码表示协处理器特定操作码L表示数据是传入ARM(为1)还是传入协处理器(为0)存放第2个操作数的协处理器寄存器在ARM中的寄存器存放第1个操作数的协处理器寄存器协处理器编号可选的协处理器特定操作码第73页/共159页ARM协处理器指令——寄存器传送指令
应用示例:
MCRp6,2,R7,c1,c2,6 ;将ARM中的R7寄存器内容传递到协处理器6的C1和C2寄存器,操作码1为2,操作码2为6MRCp5,2,R2,c3,c2,4
;将协处理器5的C3和C2寄存器,内容传递到ARM中的R2寄存器,操作码1为2,操作码2为4第74页/共159页ARM指令小节目录1.指令格式2.条件码3.存储器访问指令4.数据处理指令5.乘法指令6.ARM分支指令7.协处理器指令8.杂项指令9.伪指令第75页/共159页3.2指令集介绍ARM伪指令ARM伪指令不属于ARM指令集中的指令,是为了编程方便而定义的。伪指令可以像其它ARM指令一样使用,但在编译时这些指令将被等效的ARM指令代替。ARM伪指令有四条,分别为ADR伪指令、ADRL伪指令、LDR伪指令、NOP伪指令。第76页/共159页ARM伪指令——小范围的地址读取
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。ADR{cond}register,exprADR伪指令格式指令执行的条件码加载的目标寄存器地址表达式
地址表达式expr的取指范围:当地址值不是字对齐时,其取指范围为-255~255;当地址值是字对齐时,其取指范围为-1020~1020;当地址值是16字节对齐时,其取指范围将更大。第77页/共159页ARM伪指令——小范围的地址读取
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。...ADRR0,Delay...DelayMOVR0,r14...应用示例(源程序):使用伪指令将程序标号Delay的地址存入R0第78页/共159页...0x20ADDr1,pc,#0x3c......0x64MOVr0,r14...ARM伪指令——小范围的地址读取
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0地址程序代码第79页/共159页ARM伪指令——小范围的地址读取
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):...0x20ADDr1,pc,#0x3c......0x64MOVr0,r14...编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0ADR伪指令被汇编成一条指令实际偏移为0x44=0x64-0x20,PC值为0x28,=〉0x28+0x3c=0x44第80页/共159页ARM伪指令——小范围的地址读取
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。
应用示例2(查表):
ADRR0,DISP_TAB ;加载转换表地址
LDRBR1,[R0,R2] ;使用R2作为参数,进行查表
…DISP_TABDCB0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8第81页/共159页ARM伪指令——中等范围的地址读取
ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。ADRL{cond}register,exprADRL伪指令格式指令执行的条件码加载的目标寄存器地址表达式
地址表达式expr的取指范围:当地址值不是字对齐时,其取指范围为-64K~64K;当地址值是字对齐时,其取指范围为-256K~256K;当地址值是16字节对齐时,其取指范围将更大。第82页/共159页ARM伪指令——中等范围的地址读取
ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):使用伪指令将程序标号Delay的地址存入R0第83页/共159页ARM伪指令——中等范围的地址读取
ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):...0x20ADDr0,pc,#400x24ADDr0,r0,#0...0x68MOVr0,r14...编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0地址程序代码第84页/共159页ARM伪指令——中等范围的地址读取
ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。...ADRLR0,Delay...DelayMOVR0,r14...应用示例(源程序):...0x20ADDr0,pc,#400x24ADDr0,r0,#0...0x68MOVr0,r14...编译后的反汇编代码:使用伪指令将程序标号Delay的地址存入R0ADRL伪指令被汇编成两条指令,尽管第2条指令并没有意义第85页/共159页ARM伪指令——大范围的地址读取
LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。LDR{cond}register,=exprLDR伪指令格式指令执行的条件码加载的目标寄存器基于PC的地址表达式或外部表达式第86页/共159页ARM伪指令——大范围的地址读取
LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。应用示例(源程序):...LDRR1,=InitStack...InitStackMOVR0,LR...使用伪指令将程序标号InitStack的地址存入R1第87页/共159页ARM伪指令——大范围的地址读取
LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。应用示例(源程序):编译后的反汇编代码:...LDRR1,=InitStack...InitStackMOVR0,LR......0x60LDRR1,[0xb4]...0x64MOVR0,LR...0xb4DCD0x64使用伪指令将程序标号InitStack的地址存入R1地址程序代码第88页/共159页ARM伪指令——大范围的地址读取
LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。应用示例(源程序):编译后的反汇编代码:...LDRR1,=InitStack...InitStackMOVR0,LR......0x60LDRR1,[0xb4]
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度二手房交易过程中的物业交割协议2篇
- 铝合金门窗订购合同模板(2024版)
- 医疗废物管理课件
- 2024年度钢筋市场价格监测与合同2篇
- 2024年度产品代理与分销协议3篇
- 糖尿病引起心脑血管并发症
- 客梯货梯招标汇编资料
- 长期服务劳动合同
- 地源热泵采暖设备招标
- 网吧电脑硬件批量购买协议模板
- 道德与法治《学会沟通交流》课件
- 医疗器械经营质量工作程序目录
- 围术期过敏反应的专家共识课件
- 初中英语《Unit-6-A-Country-Music-Song-Changed-Her-Life-Forever》教学课件设计
- 安全教育、二级内容
- 中医英语入门-学堂在线网课答案修改版
- 教师资格认定申请表(补)
- 金融工程学(第五版)第4章期权工具及其配置
- 细胞生物学实验医学细胞生物学实验指导
- 初三数学老师家长会课件
- 2022年特种作业人员的管理制度
评论
0/150
提交评论