ARM指令集中数据的call指令寻址方式式有哪些

ARM寻址方式
1、 ARM寻址方式比较灵活;ARM寻址方式比较多,根据不同情况来选择;
所谓ARM寻址方式就是处理器根据指令中给出的地址信息来寻找物理地址的方式;
立即寻址:
操作数本身就在指令中给出;只要取出指令也就是取到了操作数。这个操作数被称为立即数,对应的寻址方式也就叫做立即寻址。
ADD& R0, R0, #1; R0&-R0+1
(R0+1的值赋给R0,#表示立即数);
ADD& R0, R0, #0x3f;R0&-R0+0x3f
寄存器寻址:
寄存器寻址就是利用寄存器中的数值作为操作数,这种寻址方式是各类微处理器经常采用的一种方式,也是一种执行效率较高的寻址方式。
ADD& R0,R1,R2; R0&-R0+R2
该指令执行的效果是将寄存器R1和R2的内容相加,其结果放在寄存器R0中;
寄存器间接寻址:
寄存器间接寻址就是以寄存器中的值作为操作数的地址,而操作数本身存放在存储器中。
ADD R0,R1,[R2] ;R0&-R1+[R2]
LDR&& R0,[R1];&&&&& R0&-[R1](将R1的值为地址的存储器中的数据传送到R0中。)
基址变址寻址:
基址变址寻址就是将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址;
LDR R0,[R1, #4];& R0&-[R1+4]
LDR R0,[R1, #4]!;& R0&-[R1+4]、R1&-R1+4
LDR R0,[R1], #4;& R0&-[R1]、R1&-R1+4
LDR R0,[R1, R2];& R0&-[R1+R2]
多寄存器寻址:
多寄存器寻址方式就是一条指令可以完成多个寄存器值的传送;这种寻址方式可以用一条指令完成传送最多16个通用寄存器的值、以下指令:
LDMIA R0, {R1,R2,R3,R4};&& R1&-[R0]
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& & ;&& R2&-[R0+4]
;&& R3&-[R0+8]&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;&& R4&-[R0+12]
该指令的后缀IA表示每次执行完加载/存储操作后,R0按字长度增加,因此,指令可将连续存储单元的值传送到R1~R4。
相对寻址:
相对寻址与基址变址方式相类似。相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。以下程序完成子程序的调用和返回,跳到指令BL采用了相对寻址方式:
BL& NEXT ; 跳转到子程序NEXT处执行
MOV PC,& LR  ;从子程序返回
堆栈是一种数据结构,按先进后出(First In Last Out,FILO)的工作方式,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。
递增堆栈:向高地址方向生长
递减堆栈:向低地址方向生长
满堆栈:堆栈指针指向最后压入堆栈的有效数据项
空堆栈:堆栈指针指向下一个要放入数据的空位置
阅读(...) 评论()常用 ARM 指令集及汇编
常用 ARM 指令集及汇编
ARM7TDMI(-S)指令集及汇编ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制 较为简单,ARM7TDMI(-S)具有 32 位 ARM 指令集和 16 位 Thumb 指令集,ARM 指令集效率 高,但是代码密度低,而 Thumb 指令集具有更好的代码密度,却仍然保持 ARM 的大多数 性能上的优势,它是 ARM 指令集的子集。所有 ARM 指令都是可以有条
ARM7TDMI(-S)指令集及汇编ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制 较为简单,ARM7TDMI(-S)具有 32 位 ARM 指令集和 16 位 Thumb 指令集,ARM 指令集效率 高,但是代码密度低,而 Thumb 指令集具有更好的代码密度,却仍然保持 ARM 的大多数 性能上的优势,它是 ARM 指令集的子集。所有 ARM 指令都是可以有条件执行的,而 Thumb 指令仅有一条指令具备条件执行功能。ARM 程序和 Thumb 程序可相互调用,相互之间的 状态切换开销几乎为零。ARM处理器寻址方式寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式,ARM 处理器有 9 种基本寻址方式。寄存器寻址操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直 接取出寄存器值操作。寄存器寻址指令举例如下:MOVR1,R2;R2 -> R1SUBR0,R1,R2;R1 - R2 -> R0立即寻址立即寻址指令中的操作码字段后面的地址码部分就是操作数本身,也就是说,数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(立即数)。立即寻址指令举例如下:SUBS R0,R0,#1 ;R0 & 1 -> R0MOV R0,#0xff00 ;0xff00 -> R0 立即数要以&#&为前缀,表示 16 进制数值时以&0x&表示。寄存器偏移寻址寄存器偏移寻址是ARM指令集特有的寻址方式,当第2操作数是寄存器偏移方式时, 第 2 个寄存器操作数在与第 1 个操作数结合之前,选择进行移位操作。寄存器偏移寻址方式指令举例如下:MOV R0,R2,LSL #3 ;R2 的值左移 3 位,结果放入 R0,即 R0 = R2 * 8ANDS R1,R1,R2,LSL R3 ;R2 的值左移 R3 位,然后和 R1 相与操作,结果放入 R1 可采用的移位操作如下:LSL:逻辑左移(Logical Shift Left),寄存器中字的低端空出的位补 0LSR:逻辑右移(Logical Shift Right),寄存器中字的高端空出的位补 0ASR:算术右移(Arithmetic Shift Right),移位过程中保持符号位不变,即如 果源操作数为正数,则字的高端空出的位补 0,否则补 1ROR:循环右移(Rotate Right),由字的低端移出的位填入字的高端空出的位 RRX:带扩展的循环右移(Rotate Right eXtended by 1place),操作数右移一位,高端空出的位用原 C 标志值填充。各移位操作如下图所示。0 LSL 移位操作0 LSR 移位操作ASR 移位操作ROR 移位操作C RRX 移位操作寄存器间接寻址寄存器间接寻址指令中的地址码给出的是一个通用寄存器编号,所需要的操作数保 存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针。寄存器间接寻址指令举例如下:LDR R1,[R2] ;将 R2 中的数值作为地址,取出此地址中的数据保存在 R1 中 SWP R1,R1,[R2];将如中的数值作为地址,取出此地址中的数值与 R1 中的值交换基址寻址基址寻址是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址,基址寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等。 基址寻址指令举例如下:LDR R2,[R3,#0x0F] ;将 R3 中的数值加 0x0F 作为地址,取出此地址的数值保存在 R2 中STR R1,[R0,#-2] ;将 R0 中的数值减 2 作为地址,把 R1 中的内容保存到此地址位置多寄存器寻址多寄存器寻址就是一次可以传送几个寄存器值,允许一条指令传送 16 个寄存器的 任何子集或所有寄存器。多寄存器寻址指令举例如下:LDMIA R1!,{R2-R7,R12} ;将 R1 单元中的数据读出到 R2-R7,R12,R1 自动加 1STMIA R0!,{R3-R6,R10};将 R3-R6,R10 中的数据保存到 R0 指向的地址,R0 自动加 1使用多寄存器寻址指令时,寄存器子集的顺序时由小到大的顺序排列,连续的寄存 器可用&-&连接,否则,用&,&分隔书写。堆栈寻址堆栈是特定顺序进行存取的存储区,操作顺序分为&后进先出&和&先进后出&, 堆栈寻址时隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈), 指针所指向的存储单元就是堆栈的栈顶。存储器堆栈可分为两种:向上生长:向高地址方向生长,称为递增堆栈 向下生长:向低地址方向生长,称为递减堆栈 堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个要放入的空位置,称为空堆栈。这样就有 4 中类型的堆栈表示递增和递减的满堆栈和空堆栈的各种组合。满递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的 最高地址。指令如 LDMFA,STMFA 等。空递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空 位置。指令如 LDMEA,STMEA 等。满递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址。指令如 LDMFD,STMFD 等。 空递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置。指令如 LDMED,STMED 等。 堆栈寻址指令举例如下:STMFD SP!,{R1-R7,LR} ; 将 R1~R7,LR 入栈。满递减堆栈。LDMFD SP!,{R1-R7,LR} ;数据出栈,放入 R1~R7,LR 寄存器。满递减堆栈。块拷贝寻址多寄存器传送指令用于一块数据从存储器的某一位置拷贝到另一位置。 块拷贝寻址指令举例如下:STMIAR0!,{R1-R7};将 R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之后增加,增长方向为向上增长。STMIBR0!,{R1-R7};将 R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之前增加,增长方向为向上增长。STMDAR0!,{R1-R7};将 R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之后增加,增长方向为向下增长。STMDBR0!,{R1-R7};将 R1~R7 的数据保存到存储器中,存储器指针在保存第一;个值之前增加,增长方向为向下增长。相对寻址相对寻址是基址寻址的一种变通,由程序计数器 PC 提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。相对寻址指令举例如下:BL ROUTE1 ;调用到 ROUTE1 子程序 BEQ LOOP ;条件跳转到 LOOP 标号处&LOOP MOV R2,#2&ROUTE1&指令集介绍ARM指令集指令格式基本格式{}{S} ,{,} 其中,内的项是必须的,{}内的项是可选的,如是指令助记符,是必须的,而{}为指令执行条件,是可选的,如果不写则使用默认条件 AL(无条件执行)。opcode 指令助记符,如 LDR,STR 等cond 执行条件,如 EQ,NE 等S 是否影响 CPSR 寄存器的值,书写时影响 CPSR,否则不影响 Rd 目标寄存器Rn 第一个操作数的寄存器operand2 第二个操作数指令格式举例如下:LDR R0,[R1] ;读取 R1 地址上的存储器单元内容,执行条件 AL BEQ DATAEVEN ;跳转指令,执行条件 EQ,即相等跳转到 DATAEVEN ADDS R1,R1,#1 ;加法指令,R1+1=R1 影响 CPSR 寄存器,带有 SSUBNES R1,R1,#0xD;条件执行减法运算(NE),R1-0xD=>R1,影响 CPSR 寄存器,带有 S第2个操作数在 ARM 指令中,灵活的使用第 2 个操作数能提高代码效率,第 2 个操作数的形式如 下:#immed_8r常数表达式,该常数必须对应 8 位位图,即常数是由一个 8 位的常数循环移位偶数位得到。合法常量:0x3FC、0、0xF0、200,0xF1 非法常量:0x1FE、511、0xFFFF、0x10 常数表达式应用举例如下:MOV R0,#1 ;R0=1AND R1,R2,#0x0F ;R2 与 0x0F,结果保存在 R1LDR R0,[R1],#-4 ;读取 R1 地址上的存储器单元内容,且 R1=R1-4Rm寄存器方式,在寄存器方式下操作数即为寄存器的数值。 寄存器方式应用举例:SUBR1,R1,R2;R1-R2=>R1MOVPC,R0;PC=R0,程序跳转到指定地址LDRR0,[R1],-R2;读取 R1 地址上的存储器单元内容并存入 R0,且 R1=R1-R2Rm,shift寄存器移位方式。将寄存器的移位结果作为操作数,但 RM 值保存不变,移位方法 如下:ASR #n 算术右移 n 位(1&n&32) LSL #n 逻辑左移 n 位(1&n&31) LSR #n 逻辑左移 n 位(1&n&32) ROR #n 循环右移 n 位(1&n&31) RRX 带扩展的循环右移 1 位type Rs 其中,type 为 ASR,LSL,和 ROR 中的一种;Rs 偏移量寄存器,低 8 位有效,若其值大于或等于 32,则第 2 个操作数的结果为 0(ASR、ROR 例外)。寄存器偏移方式应用举例:ADD R1,R1,R1,LSL #3 ;R1=R1*9SUB R1,R1,R2,LSR#2 ;R1=R1-R2*4R15 为处理器的程序计数器 PC,一般不要对其进行操作,而且有些指令是不允许使 用 R15,如 UMULL 指令。条件码使用指令条件码,可实现高效的逻辑操作,提高代码效率。 条件码表条件码助记符标志含义EQZ=1相等NEZ=0不相等CS/HSC=1无符号数大于或等于CC/LOC=0无符号数小于MIN=1负数PLN=0正数或零VSV=1溢出VCV=0没有溢出HIC=1,Z=0无符号数大于LSC=0,Z=1无符号数小于或等于GEN=V带符号数大于或等于LTN!=V带符号数小于GTZ=0,N=V带符号数大于LEZ=1,N!=V带符号数小于或等于AL任何无条件执行(指令默认条件)对于 Thumb 指令集,只有 B 指令具有条件码执行功能,此指令条件码同表 2.1,但如果为无条件执行时,条件码助记符&AL&不能在指令中书写。 条件码应用举例如下:比较两个值大小,并进行相应加 1 处理,C 代码为if(a>b)a++;else b++;对应的 ARM 指令如下。其 R0 为 a,R1 为 b。 CMP R0,R1 ;R0 与 R1 比较ADDHI R0,R0,#1 ;若 R0>R1,则 R0=R0+1ADDLS R1,R1,#1 ;若 R0<=R1,则 R1=R1+1 若两个条件均成立,则将这两个数值相加,C 代码为If((a!=10)&&(b!=20)) a=a+b;对应的 ARM 指令如下.其中 R0 为 a,R1 为 b. CMP R0,#10 ;比较 R0 是否为 10CMPNE R1,#20 ;若 R0 不为 10,则比较 R1 是否 20ADDNE R0,R0,R1 ;若 R0 不为 10 且 R1 不为 20,指令执行,R0=R0+R1ARM存储器访问指令ARM 处理是加载/存储体系结构的典型的 RISC 处理器,对存储器的访问只能使用加 载和存储指令实现。ARM 的加载/存储指令是可以实现字、半字、,无符/有符字节操作; 批量加载/存储指令可实现一条指令加载/存储多个寄存器的内容,大大提高效率;SWP 指令是一条寄存器和存储器内容交换的指令,可用于信号量操作等。ARM 处理器是冯. 诺依曼存储结构,程序空间、RAM 空间及 IO 映射空间统一编址,除对对 RAM 操作以外, 对外围 IO、程序数据的访问均要通过加载/存储指令进行。ARM 存储访问指令表助记符说明操作条件码位置LDR Rd,addressing加载字数据Rd[addressing],addressing 索引LDR{cond}LDRB Rd,addressing加载无符字节数据Rd[addressing],addressing 索引LDR{cond}BLDRT Rd,addressing以用户模式加载字数据Rd[addressing],addressing 索引LDR{cond}TLDRBT Rd,addressing以用户模式加载无符号字数据Rd[addressing],addressing 索引LDR{cond}BTLDRH Rd,addressing加载无符半字数据Rd[addressing],addressing 索引LDR{cond}HLDRSB Rd,addressing加载有符字节数据Rd[addressing],addressing 索引LDR{cond}SBLDRSH Rd,addressing加载有符半字数据Rd[addressing],addressing 索引LDR{cond}SHSTR Rd,addressing存储字数据[addressing]Rd,addressing 索引STR{cond}STRB Rd,addressing存储字节数据[addressing]Rd,addressing 索引STR{cond}BSTRT Rd,addressing以用户模式存储字数据[addressing]Rd,addressing 索引STR{cond}TSRTBT Rd,addressing以用户模式存储字节数据[addressing]Rd,addressing 索引STR{cond}BTSTRH Rd,addressing存储半字数据[addressing]Rd,addressing 索引STR{cond}HLDM{mode} Rn{!},reglist批量(寄存器)加载reglist[Rn&],Rn 回存等LDM{cond}{more}STM{mode} Rn{!},rtglist批量(寄存器)存储[Rn&] reglist,Rn 回存等STM{cond}{more}SWP Rd,Rm,Rn寄存器和存储器字数据交换Rd[Rd],[Rn][Rm](Rn&Rd 或 Rm)SWP{cond}SWPB Rd,Rm,Rn寄存器和存储器字节数据交换Rd[Rd],[Rn][Rm](Rn&Rd 或 Rm)SWP{cond}BXLDR和STR加载/存储字和无符号字节指令.使用单一数据传送指令(STR 和 LDR)来装载和存储 单一字节或字的数据从/到内存.LDR 指令用于从内存中读取数据放入寄存器中;STR 指 令用于将寄存器中的数据保存到内存.指令格式如下:LDR{cond}{T} Rd,;加载指定地址上的数据(字),放入 Rd 中 STR{cond}{T} Rd,;存储数据(字)到指定地址的存储单元,要存储的数据在 Rd 中 LDR{cond}B{T} Rd,;加载字节数据,放入 Rd 中,即 Rd 最低字节有效,高 24 位清零STR{cond}B{T} Rd,;存储字节数据,要存储的数据在 Rd,最低字节有效其中,T 为可选后缀,若指令有 T,那么即使处理器是在特权模式下,存储系统也将访 问看成是处理器是在用户模式下.T 在用户模式下无效,不能与前索引偏移一起使用 T. LDR/STR 指令寻址是非常灵活的,由两部分组成,一部分为一个基址寄存器,可以为任一 个通用寄存器,另一部分为一个地址偏移量.地址偏移量有以下 3 种格式:(1) 立即数.立即数可以是一个无符号数值,这个数据可以加到基址寄存器,也可 以从基址寄存器中减去这个数值.指令举例如下:LDR R1,[R0,#0x12] ;将 R0+0x12 地址处的数据读出,保存到 R1 中(R0 的值不变) LDR R1,[R0,#-0x12];将 R0-0x12 地址处的数据读出,保存到 R1 中(R0 的值不变) LDR R1,[R0] ;将 R0 地址处的数据读出,保存到 R1 中(零偏移) (2)寄存器.寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值.指令举例值.指令举例如下:LDR R1,[R0,R2] ;将 R0+R2 地址的数据计读出,保存到 R1 中(R0 的值不变) LDR R1,[R0,-R2] ;将 R0-R2 地址处的数据计读出,保存到 R1 中(R0 的值不变) (3)寄存器及移位常数.寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值.指令举例如下:LDR R1,[R0,R2,LSL #2] ;将 R0+R2*4 地址处的数据读出,保存到 R1 中(R0,R2 的值不变) LDR R1,[R0,-R2,LSL #2];将 R0-R2*4 地址处的数据计读出,保存到 R1 中(R0,R2 的值不变) 从寻址方式的地址计算方法分,加载/存储指令有以下 4 种形式:(1)零偏移.Rn 的值作为传送数据的地址,即地址偏移量为 0.指令举例如下: LDR Rd,[Rn](2)前索引偏移.在数据传送之前,将偏移量加到 Rn 中,其结果作为传送数据的存储地址.若使用后缀&!&,则结果写回到 Rn 中,且 Rn 值不允许为 R15.指令举例如下:LDR Rd,[Rn,#0x04]! LDR Rd,[Rn,#-0x04] (3)程序相对偏移.程序相对偏移是索引形式的另一个版本.汇编器由 PC 寄存器计算偏移量,并将 PC 寄存器作为 Rn 生成前索引指令.不能使用后缀&!&.指令举例如下: LDR Rd,label 为程序标号,label 必须是在当前指令的&4KB 范围内 (4) 后索引偏移.Rn 的值用做传送数据的存储地址.在数据传送后,将偏移量与 Rn相加,结果写回到 Rn 中.Rn 不允许是 R15.指令举例如下:LDR Rd,[Rn],#0x04地址对准--大多数情况下,必须保证用于 32 位传送的地址是 32 位对准的. 加载/存储字和无符号字节指令举例如下:LDR R2,[R5] ;加载 R5 指定地址上的数据(字),放入 R2 中STR R1,[R0,#0x04] ;将 R1 的数据存储到 R0+0x04 存储单元,R0 值不变LDRB R3,[R2],#1 ;读取 R2 地址上的一字节数据,并保存到 R3 中,R2=R3+1STRB R6,[R7] ;读R6的数据保存到R7指定的地址中,只存储一字节数据 加载/存储半字和带符号字节.这类 LDR/STR 指令可能加载带符字节\加载带符号半字、加载/存储无符号半字.偏移量格式、寻址方式与加载/存储字和无符号字节指令相同.指令格式如下:LDR{cond}SB Rd, ;加载指定地址上的数据(带符号字节),放入 Rd 中 LDR{cond}SH Rd, ;加载指定地址上的数据(带符号字节),放入 Rd 中 LDR{cond}H Rd, ;加载半字数据,放入 Rd 中,即 Rd 最低 16 位有效,高 16 位清零 STR{cond}H Rd, ;存储半字数据,要存储的数据在 Rd,最低 16 位有效 说明:带符号位半字/字节加载是指带符号位加载扩展到 32 位;无符号位半字加载是指零扩展到 32 位.地址对准--对半字传送的地址必须为偶数.非半字对准的半字加载将使 Rd 内容不 可靠,非半字对准的半字存储将使指定地址的 2 字节存储内容不可靠.加载/存储半字和带符号字节指令举例如下:LDRSB R1[R0,R3] ;将 R0+R3 地址上的字节数据读出到 R1,高 24 位用符号位扩展 LDRSH R1,[R9] ;将 R9 地址上的半字数据读出到 R1,高 16 位用符号位扩展 LDRH R6,[R2],#2 ;将 R2 地址上的半字数据读出到 R6,高 16 位用零扩展,,R2=R2+1SHRH R1,[R0,#2]!;将 R1 的数据保存到 R2+2 地址中,只存储低 2 字节数据,R0=R0+2LDR/STR 指令用于对内存变量的访问,内存缓冲区数据的访问、查表、外围部件的 控制操作等等,若使用 LDR 指令加载数据到 PC 寄存器,则实现程序跳转功能,这样也就实现了程序散转。变量的访问NumCount EQU 0x43 ;定义变量 NumCountGPIO 设置&LDR R0,=NumC使用 LDR 伪指令装载 NumCount 的地址到 R0LDR R1,[R0] ;取出变量值ADD R1,R1,#1 ;NumCount=NumCount+1STR R1,[R0] ;保存变量值&GPIO-BASE EQU 0Xe0028 ;定义 GPIO 寄存器的基地址&LDR R0,=GPIO-BASELDR R1,=0x00FFFF00 ;装载 32 位立即数,即设置值STR R1,[R0,#0x0C] ;IODIR=0x00FFFF00, IODIR 的地址为 0xE002800CMOV R1,#0x00F00STR R1,[R0,#0x04] ;IOSET=0x00F00,IOSET 的地址为 0xE0028004&程序散转&MOV R2,R2,LSL #2 ;功能号乘上 4,以便查表LDR PC,[PC,R2] ;查表取得对应功能子程序地址,并跳转 NOPFUN-TAB DCD FUN-SUB0DCD FUN-SUB1DCD FUN-SUB2&XLDM和STM批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数 据.LDM 为加载多个寄存器,STM 为存储多个寄存器.允许一条指令传送 16 个寄存器的任 何子集或所有寄存器.指令格式如下:LDM{cond} Rn{!},reglist{^}STM{cond} Rn{!},reglist{^}LDM /STM 的主要用途是现场保护、数据、参数传送等。其模式有 8 种,如下:(前 面 4 种用于数据块的传输,后面 4 种是堆栈操作)(1) IA:每次传送后地址加 4 (2) IB:每次传送前地址加 4 (3) DA:每次传送后地址减 4 (4) DB:每次传送前地址减 4 (5) FD:满递减堆栈(6) ED:空递增堆栈 (7) FA:满递增堆栈 (8) EA:空递增堆栈其中,寄存器Rn为基址寄存器,装有传送数据的初始地址,Rn不允许为R15;后缀&!& 表示最后的地址写回到Rn中;寄存器列表reglist可包含多于一个寄存器或寄存器范围, 使用&,&分开,如{R1,R2,R6-R9},寄存器排列由小到大排列;&^&后缀不允许在用户 模式呈系统模式下使用,若在 LDM 指令用寄存器列表中包含有 PC 时使用,那么除了正 常的多寄存器传送外,将 SPSR 拷贝到 CPSR 中,这可用于异常处理返回;使用&^&后 缀进行数据传送且寄存器列表不包含 PC 时,加载/存储的是用户模式的寄存器,而不是 当前模式的寄存器。地址对准――这些指令忽略地址的位[1:0] 批量加载/存储指令举例如下:LDMIA R0!,{R3-R9} ;加载 R0 指向的地址上的多字数据,保存到 R3~R9 中,R0 值更新 STMIA R1!,{R3-R9} ;将 R3~R9 的数据存储到 R1 指向的地址上,R1 值更新 STMFD SP!,{R0-R7,LR} ;现场保存,将 R0~R7、LR 入栈LDMFD SP!,{R0-R7,PC}^;恢复现场,异常处理返回 在进行数据时,先设置好源数据指针,然后使用块拷贝寻址指令 LDMIA/STMIA、LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB 进行读取和存储。而进行堆栈操作时,则要先设置堆栈指针,一般使用 SP 然后使用堆栈寻址指令 STMFD/LDMFD、STMED。LDMED、 STMFA/LDMFA、STMEA/LDMEA 实现堆栈操作。多寄存器传送指令示意图如图所示,其中 R1 为指令执行前的基址寄存器,R1 则为指令执行完后的基址寄存器. R1&R7R6R1 R5 4008H4004H4Ha)指令 STMIA R1!,{R5-R7}R1&R1R7R6R5 4008H4004H4Hb)指令 STMIB R1!,{R5-R7}R1R1&R7R6R5 4008H4004H4Hc)指令 STMDA R1!, {R5-R7}R1R1&R7R6 4008H R5 4004H4Hd)指令 STMDB R1!,{R5-R7}数据是存储在基址寄存器的地址之上还是之下,地址是在存储第一个值之前还是之后增加还是减少.多寄存器传送指令映射向上生长向下生长满空满空增加之前STMIBLDMIBSTMFALDMED之后STMIALDMIASTMEALDMFD增加之前LDMDBSTMDBLDMEASTMFD之后LDMDASTMDALDMFASTMED使用 LDM/STM 进行数据:&LDR R0,=SrcD设置源数据地址 LDR R1,=DstD设置目标地址LDMIA R0,{R2-R9} ;加载 8 字数据到寄存器 R2~R9STMIA R1,{R2~R9} ;存储寄存器 R2~R9 到目标地址 使用 LDM/STM 进行现场寄存器保护,常在子程序中或异常处理使用: SENDBYTESTMFD SP!,{R0-R7,LR} ;寄存器入堆&BL DELAY ;调用 DELAY 子程序&LDMFD SP!,{R0-R7,PC} ;恢复寄存器,并返回XSWP寄存器和存储器交换指令.SWP 指令用于将一个内存单元(该单元地址放在寄存器 Rn 中)的内容读取到一个寄存器 Rd 中,同时将另一个寄存器 Rm 的内容写入到该内存单 元中.使用 SWP 可实现信号量操作.指令格式如下: SWP{cond}{B} Rd,Rm,[Rn]其中,B 为可选后缀,若有 B,则交换字节,否则交换 32 位字:Rd 为数据从存储器加载到的寄存器;Rm 的数据用于存储到存储器中,若 Rm 与 Rn 相同,则为寄存器与存储器内容 进行交换;Rn 为要进行数据交换的存储器地址,Rn 不能与 Rd 和 Rm 相同.SWP 指令举例如下:SWP R1,R1,[R0] ;将 R1 的内容与 R0 指向的存储单元的内容进行交换SWP R1,R2,,[R0] ;将R0指向的存储单元内容读取一字节数据到R1中(高24 位清零),并将 R2 的内容写入到该内存单元中(最低字节有效) 使用 SWP 指令可以方便地进行信号量的操作:12C_SEM EQU 0x43&12C_SEM_WAITMOV R0,#0LDR R0,=12C_SEMSWP R1,R1,[R0] ;取出信号量,并设置其为 0CMP R1,#0 ;判断是否有信号BEQ 12C_SEM_WAIT ;若没有信号,则等待ARM数据处理指令数据处理指令大致可分为 3 类;数据传送指令(如 MOV、MVN),算术逻辑运算指令 (如 ADD,SUM,AND),比较指令(如 CMP,TST).数据处理指令只能对寄存器的内容进行操作. 所有 ARM 数据处理指令均可选择使用 S 后缀,以影响状态标志.比较指令 CMP,CMN,TST 和 TEQ 不需要后缀 S,它们会直接影响状态标志.ARM 数据处理指令助记符号说明操作条件码位置MOV Rd ,operand2数据转送Rdoperand2MOV {cond}{S}MVN Rd ,operand2数据非转送Rd(operand2)MVN {cond}{S}ADD Rd,Rn operand2加法运算指令RdRn+operand2ADD {cond}{S}SUB Rd,Rn operand2减法运算指令RdRn-operand2SUB {cond}{S}RSB Rd,Rn operand2逆向减法指令Rdoperand2-RnRSB {cond}{S}ADC Rd,Rn operand2带进位加法RdRn+operand2+carryADC {cond}{S}SBC Rd,Rn operand2带进位减法指令RdRn-operand2-(NOT)CarrySBC {cond}{S}RSC Rd,Rn operand2带进位逆向减法指令Rdoperand2-Rn-(NOT)CarryRSC {cond}{S}AND Rd,Rn operand2逻辑与操作指令RdRn&operand2AND {cond}{S}ORR Rd,Rn operand2逻辑或操作指令RdRnoperand2ORR {cond}{S}EOR Rd,Rn operand2逻辑异或操作指令RdRn^operand2EOR {cond}{S}BIC Rd,Rn operand2位清除指令RdRn&(~operand2)BIC {cond}{S}CMP Rn,operand2比较指令标志 N、Z、C、VRn-operand2CMP {cond}CMN Rn,operand2负数比较指令标志 N、Z、C、VRn+operand2CMN {cond}TST Rn,operand2位测试指令标志 N、Z、C、VRn&operand2TST {cond}TEQ Rn,operand2相等测试指令标志 N、Z、C、VRn^operand2TEQ {cond}数据传送指令XMOV数据传送指令.将 8 位图立即数或寄存器(operant2)传送到目标寄存器 Rd,可用于 移位运算等操作.指令格式如下:MOV{cond}{S} Rd,operand2MOV 指令举例如下:MOVR1#0x10;R1=0x10MOVR0,R1;R0=R1MOVSR3,R1,LSL#2;R3=R1<<2,并影响标志位MOVPC,LR;PC=LR ,子程序返回XMVN数据非传送指令.将 8 位图立即数或寄存器(operand2)按位取反后传送到目标寄存 器(Rd),因为其具有取反功能,所以可以装载范围更广的立即数.指令格式如下:MVN{cond}{S} Rd,operand2MVN 指令举例如下:MVNR1,#0xFF;R1=0xFFFFFF00MVNR1,R2;将 R2 取反,结果存到 R1算术逻辑运算指令XADD加法运算指令.将 operand2 数据与 Rn 的值相加,结果保存到 Rd 寄存器.指令格式如下:ADD{cond}{S} Rd,Rn,operand2ADD 指令举例如下:ADDS R1,R1,#1 ;R1=R1+1ADD R1,R1,R2 ;R1=R1+R2ADDS R3,R1,R2,LSL #2 ;R3=R1+R2<<2XSUB减法运算指令.用寄存器 Rn 减去 operand2.结果保存到 Rd 中.指令格式如下: SUB{cond}{S} Rd,Rn,operand2SUB 指令举例如下SUBS R0,R0,#1 ;R0=R0-1SUBS R2,R1,R2 ;R2=R1-R2SUB R6,R7,#0x10 ;R6=R7-0x10XRSB逆向减法指令.用寄存器 operand2 减法 Rn,结果保存到 Rd 中.指令格式如下: RSB{cond}{S} Rd,Rn,operand2SUB 指令举例如下RSB R3,R1,#0xFF00 ;R3=0xFF00-R1RSBS R1,R2,R2,LSL #2 ;R1=R2<<2-R2=R2&3RSB R0,R1,#0 ;R0=-R1XADC带进位加法指令.将 operand2 的数据与 Rn 的值相加,再加上 CPSR 中的 C 条件标志位.结果保存到 Rd 寄存器.指令格式如下;ADC{cond}{S} Rd,Rn,operand2ADC 指令举例如下:ADDSR0,R0,R2ADCR1,R1,R3;使用 ADC 实现 64 位加法,(R1、R0)=(R1、R0)+(R3、R2)XSBC带进位减法指令。用寄存器 Rn 减去 operand2,再减去 CPSR 中的 C 条件标志位的非(即若 C 标志清零,则结果减去 1),结果保存到 Rd 中。指令格式如下:SCB{cond}{S}Rd,Rn,operand2SBC 指令举例如下SUBSR0,R0,R2SBCR1,R1,R3;使用 SBC 实现 64 位减法,(R1,R0)-(R3,R2)XRSC带进位逆向减法指令.用寄存器 operand2 减去 Rn,再减去 CPSR 中的 C 条件标志位, 结果保存到 Rd 中.指令格式如下:RSC{cond}{S} Rd,Rn,operand2RSC 指令举例如下:RSBSR2,R0,#0RSCR3,R1,#0;使用 RSC 指令实现求 64 位数值的负数XAND逻辑与操作指令.将 operand2 值与寄存器 Rn 的值按位作逻辑与操作,结果保存到 Rd 中.指令格式如下:AND{cond}{S} Rd,Rn,operand2AND 指令举例如下:ANDS R0,R0,#x01 ;R0=R0&0x01,取出最低位数据 AND R2,R1,R3 ;R2=R1&R3XORR逻辑或操作指令.将operand2的值与寄存器Rn的值按位作逻辑或操作,结果保存到 Rd 中.指令格式如下:ORR{cond}{S} Rd,Rn,operand2ORR 指令举例如下:ORR R0,R0,#x0F ;将 R0 的低 4 位置 1MOV R1,R2,LSR #4ORR R3,R1,R3,LSL #8 ;使用 ORR 指令将近 R2 的高 8 位数据移入到 R3低8位中XEOR逻辑异或操作指令.将operand2 的值与寄存器Rn的值按位作逻辑异或操作,结果保 存到 Rd 中.指令格式如下:EOR{cond}{S}Rd,Rn,operand2EOR 指令举例如下:EOR R1,R1,#0x0F ;将 R1 的低 4 位取反EOR R2,R1,R0 ;R2=R1^R0EORS R0,R5,#0x01 ;将 R5 和 0x01 进行逻辑异或,结果保存到 R0,并影响标志位XBIC位清除指令.将寄存器Rn的值与operand2的值的反码按位作逻辑与操作,结果保存 到 Rd 中.指令格式如下:BIC{cond}{S}Rd,Rn,operand2BIC 指令举例如下:BICR1,R1,#0x0F;将 R1 的低 4 位清零,其它位不变BICR1,R2,R3;将拭的反码和 R2 相逻辑与,结果保存到 R1比较指令XCMP比较指令.指令使用寄存器 Rn 的值减去 operand2 的值,根据操作的结果理新 CPSR 中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行.指令格式 如下:CMP{cond} Rn,operand2CMP 指令举例如下:CMP R1,#10 ;R1 与 10 比较,设置相关标志位 CMP R1,R2 ;R1 与 R2 比较,设置相关标志位CMP 指令与 SUBS 指令的区别在于 CMP 指令不保存运算结果.在进行两个数据大小判断时,常用 CMP 指令及相应的条件码来操作.XCMN负数比较指令.指令使用寄存器 Rn 与值加上 operand2 的值,根据操作的结果理新 CPSR 中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行,指令 格式如下:CMN{cond} Rn,operand2CMN R0,#1 ;R0+1,判断 R0 是否为 1 的补码,若是 Z 置位CMN 指令与 ADDS 指令的区别在于 CMN 指令不保存运算结果.CMN 指令可用于负数比较,比如 CMNR0,#1 指令则表示 R0 与-1 比较,若 R0 为-(即 1 的补码),则 Z 置位,否则 Z 复位.XTST位测试指令.指令将寄存器Rn的值与operand2的值按位作逻辑与操作,根据操作的结果理新 CPSR 中相应的条件标志位,以便后面指令根据相应的条件标志来判断是否执行.指令格式如下:TST{cond} Rn,operand2TST 指令举例如下:TST R0,#0x01 ;判断 R0 的最低位是否为 0TST R1,#0x0F ;判断 R1 的低 4 位是否为 0TST 指令与 ANDS 指令的区别在于 TST4 指令不保存运算结果.TST 指令通常于 EQ,NE 条件码配合使用,当所有测试位均为 0 时,EQ 有效,而只要有一个测试为不为 0,则 NE 有 效.XTEQ相等测试指令.指令寄存器Rn的值与operand2的值按位作逻辑异或操作,根据操作的结果理新 CPSR 中相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行.指令格式如下:TEQ{cond} Rn,operand2TEQ 指令举例如下:TEQ R0,R1 ;比较 R0 与 R1 是否相等(不影响 V 位和 C 位)TST 指令与 EORS 指令的区别在于 TST 指令不保存运算结果.使用 TEQ 进行相等测试, 常与 EQNE 条件码配合使用,当两个数据相等时,EQ 有效,否则 NE 有效.乘法指令ARM7TDMI(-S)具有 32&32 乘法指令,32&32 乘加指令,32&32 结果为 64 位的乘/ 乘法指令.ARM 乘法指令助记符说明操作条件码位置MUL Rd,Rm,Rs32 位乘法指令RdRm*Rs (Rd&Rm)MUL{cond}{S}MLA Rd,Rm,Rs,Rn32 位乘加指令RdRm*Rs+Rn (Rd&Rm)MLA{cond}{S}UMULL RdLo,RdHi,Rm,Rs64 位无符号乘法指令(RdLo,RdHi)Rm*RsUMULL{cond}{S}UMLAL RdLo,RdHi,Rm,Rs64 位无符号乘加指令(RdLo,RdHi)Rm*Rs+(RdLo,RdHi)UMLAL{cond}{S}SMULL RdLo,RdHi,Rm,Rs64 位有符号乘法指令(RdLo,RdHi)Rm*RsSMULL{cond}{S}SMLAL RdLo,RdHi,Rm,Rs64 位有符号乘加指令(RdLo,RdHi)Rm*Rs+(RdLo,RdHi)SMLAL{cond}{S}XMUL32 位乘法指令.指令将 Rm 和 Rs 中的值相乘,结果的低 32 位保存到 Rd 中.指令格式如下:MUL{cond}{S} Rd,Rm,RsMUL 指令举例如下:MUL R1,R2,R3 ;R1=R2&R3MULS R0,R3,R7 ;R0=R3&R7,同时设置 CPSR 中的 N 位和 Z 位XMLA32 位乘加指令.指令将 Rm 和 Rs 中的值相乘,再将乘积加上第 3 个操作数,结果的低32 位保存到 Rd 中.指令格式如下: MLA{cond}{S} Rd,Rm,Rs,Rn MLA 指令举例如下:MLA R1,R2,R3,R0 ;R1=R2&R3+10XUMULL64 位无符号乘法指令.指令将 Rm 和 Rs 中的值作无符号数相乘,结果的低 32 位保存到 RsLo 中,而高 32 位保存到 RdHi 中,.指令格式如下:UMULL{cond}{S} RdLo,RdHi,Rm,RsUMULL 指令举例如下:UMULL R0,R1,R5,R8 ;(R1、R0)=R5&R8XUMLAL64 位无符号乘加指令.指令将 Rm 和 Rs 中的值作无符号数相乘,64 位乘积与 RdHi,RdLo 相加,结果的低 32 位保存到 RdLo 中,而高 32 位保存到 RdHi 中.指令格式如 下:UMLAL{cond}{S} RdLo,RdHi,Rm,RsUMLAL 指令举例如下:UMLAL R0,R1,R5,R8 ;(R1,R0)=R5&R8+(R1,R0)XSMULL64 位有符号乘法指令.指令将 Rm 和 Rs 中的值作有符号数相乘,结果的低 32 位保存到 RdLo 中,而高 32 位保存到 RdHi 中.指令格式如下:SMULL{cond}{S} RdLo,RdHi,Rm,RsSMULL 指令举例如下:SMULL R2,R3,R7,R6 ;(R3,R2)=R7&R6XSMLAL64 位有符号乘加指令.指令将 Rm 和 Rs 中的值作有符号数相乘,64 位乘积与 RdHi,RdLo,相加,结果的低 32 位保存到 RdLo 中,而高 32 位保存到 RdHi 中.指令格式如下:SMLAL{cond}{S} RdLo,RdHi,Rm,RsSMLAL 指令举例如下:SMLAL R2,R3,R7,R6 ;(R3,R2)=R7&R6+(R3,R2)ARM跳转指令在 ARM 中有两种方式可以实现程序的跳转,一种是使用跳转指令直接跳转,另一种 则是直接向 PC 寄存器赋值实现跳转.跳转指令有跳转指令 B,带链接的跳转指令 BL 带状 态切换的跳转指令 BX.跳转指令助记符说明操作条件码位置B label跳转指令PclabelB{cond}BL label带链接的跳转指令LRPC-4, PClabelBL{cond}BX Rm带状态切换的跳转指令PClabel,切换处理状态BX{cond}XB跳转指令.跳转到指定的地址执行程序.指令格式如下; B{cond} label跳转指令 B 举例如下:B WAITA ;跳转到 WAITA 标号处B 0x1234 ;跳转到绝对地址 0x1234 处 跳转到指令 B 限制在当前指令的&32Mb 的范围内.XBL带链接的跳转指令.指令将下一条指令的地址拷贝到 R14(即 LR)链接寄存器中,然后跳转到指定地址运行程序.指令格式如下:BL{cond} label 带链接的跳转指令 BL 举例如下: BL DELAY跳转指令 B 限制在当前指令的&32MB 的范围内.BL 指令用于子程序调用XBX带状态切换的跳转指令.跳转到 Rm 指定的地址执行程序,若 Rm 的位[0]为 1,则跳转时自动将 CPSR 中的标志 T 置位,即把目标地址的代码解释为 Thumb 代码;若 Rm 的位[0]为 0,则跳转时自动将 CPSR 中的标志 T 复位,即把目标地址的代码解释为 ARM 代码.指令 格式如下:BX{cond} Rm 带状态切换的跳转指令 BX 举例如下 ADRL R0,ThumbFun+1BX R0 ;跳转到R0指定的地址,并根据R0的最低位来切换处理器状态ARM协处理器指令ARM 支持协处理器操作,协处理器的控制要通过协处理器命令实现.ARM 协处理器指令助记符说明操作条件码位置CDPcoproc,opcodel,CRd,CRn,CRm{,opcode2}协处理器数据操作指令取决于协处理器CDP{cond}LDC{L} coproc,CRd〈地址〉协处理器数据读取指令取决于协处理器LDC{cond}{L}STC{L} coproc,CRd,〈地址〉协处理器数据写入指令取决于协处理器STC{cond}{L}MCR coproc, opcodel,Rd,CRn,{,opcode2}ARM 寄存器到协处理器寄存器的数据传送指令取决于协处理器MCR{cond}MRC coproc, opcodel,Rd,CRn,{,opcode2}协处理器寄存器到 ARM 寄存器到数据传送指令取决于协处理器MCR{cond}XCDP协处理器数据操作指令.ARM 处理器通过 CDP 指令通知 ARM 协处理器执行特定的操作.该操作由协处理器完成,即对命令的参数的解释与协处理器有关,指令的使用取决于 协处理器.若协处理器不能成功地执行该操作,将产生未定义指令异常中断.指令格式如 下:CDP{cond} coproc,opcodel,CRd,CRn,CRm{,opcode2}其中: coproc 指令操作的协处理器名.标准名为 pn,n 为 0~15. opcodel 协处理器的特定操作码CRd 作为目标寄存器的协处理器寄存器. CRN 存放第 1 个操作数的协处理器寄存器.CRm 存放第 2 个操作数的协处理器寄存器.Opcode2 可选的协处理器特定操作码.CDP指令举例如下:CDPp7,0,c0,c2,c3,0;协处理器 7 操作,操作码为 0,可选操作码为 0CDPXLDCp6,1,c3,c4,c5;协处理器操作,操作码为 1协处理器数据读取指令.LDC 指令从某一连续的内存单元将数据读取到协处理器的寄存器中.协处理器数据的数据的传送,由协处理器来控传送的字数.若协处理器不能成 功地执行该操作,将产生未定义指令异常中断.指令格式如下;LDC{cond}{L} coproc,CRd,其中: L 可选后缀,指明是长整数传送.coproc 指令操作的协处理器名.标准名为 pn,n 为 0~15CRd 作为目标寄存的协处理器寄存器. 指定的内存地址 LDC 指令举例如下:LDC p5,c2,[R2,#4];读取 R2+4 指向的内存单元的数据,传送到协处理器 p5 的 c2 寄存器中LDC p6,c2,[R1] ;读取是指向的内存单元的数据,传送到协处理器 p6 的 c2 寄存器中XSTC协处理器数据写入指令.STC 指令将协处理器的寄存器数据写入到某一连续的内存 单元中.进行协处理器数据的数据传送,由协处理器来控制传送的字数.若协处理器不能 成功地执行该操作,将产生未定义指令异常中断.指令格式如下;STC{cond}{L} coproc,CRd, 其中:L 可选后缀,指明是长整数传送.coproc 指令操作的协处理器名.标准名为 pn,n 为 0~15CRd 作为目标寄存的协处理器寄存器. 指定的内存地址STC 指令举例如下: STC p5,c1,[R0]STC p5,c1,[Ro,#-0x04]XMCRARM寄存器到协处理器寄存器的数据传送指令.MCR指令将ARM处理器的寄存器中的 数据传送到协处理器的寄存器中.若协处理器不能成功地执行该操作,将产生未定义指 令异常中断.指令格式如下;MCR{cond} coproc,opcodel,Rd,CRn,CRm{,opcode2}其中 coproc 指令操作的协处理器名.标准名为 pn,n 为 0~15. cpcodel 协处理器的特定操作码.CRD 作为目标寄存器的协处理器寄存器. CRn 存放第 1 个操作数的协处理器寄存器 CRm 存放第 2 个操作数的协处理器寄存器. Opcode2 可选的协处理器特定操作码.MCR 指令举例如下:MCR p6,2,R7,c1,c2, MCR P7,0,R1,c3,c2,1,XMRC协处理器寄存器到 ARM 寄存器到的数据传送指令.MRC 指令将协处理器寄存器中的 数据传送到 ARM 处理器的寄存器中.若协处理器不能成功地执行该操作.将产生未定义 异常中断.指令格式如下.MRC {cond} coproc,opcodel,Rd,CRn,CRm{,opcode2}其中 coproc 指令操作的协处理器名.标准名为 pn,n,为 0~15 opcodel 协处理器的特定操作码.CRd 作为目标寄存器的协处理器寄存器.CRn 存放第 1 个操作数的协处理器寄存器.CRm 存放第 2 个操作数的协处理器寄存器. opcode2 可选的协处理器特定操作码.MRC 指令举例如下 MRC p5,2,R2,c3,c2MRC p7,0,R0,c1,c2,1ARM杂项指令助记符说明操作条件码位置SWI immed_24软中断指令产生软中断,处理器进入管理模式SWI{cond}MRS Rd,psr读状态寄存器指令Rdpsr,psr 为 CPSR 或 SPSRMRS{cond}MSR psr_fields,Rd/#immed_8r写状态寄存器指令psr_fieldsRd/#immed_8r,psr 为 CPSR 或 SPSRMSR{cond}XSWI软中断指令.SWI 指令用于产生软中断,从而实现在用户模式变换到管理模式,CPSR 保存到管理模式的 SPSR 中,执行转移到 SWI 向量,在其它模式下也可使用 SWI 指令,处理 同样地切换到管理模式.指令格式如下;SWI{cond} immed_24其中 immed_24 24 位立即数,值为 0~16215 之间的整数 SWI 指令举例如下:SWI 0 ;软中断,中断立即数为 0SWI 0x123456 ;软中断,中断立即数为 0x123456使用 SWI 指令时,通常使用以下两种方法进行传递参数,SWI 异常中断处理程序就可 以提供相关的服务,这两种方法均是用户软件协定.SWI 异常中断处理程序要通过读取 引起软中断的 SWI 指令,以取得 24 位立即数.1.指令 24 位的立即数指定了用户请求的服务类型,参数通过用寄存器传递 MOV R0,#34 ;设置了功能号为 34SWI 12 ;调用 12 号软中断2.指令中的24位立即数被忽略,用户请求的服务类型由寄存器R0的值决定,参数通过其它的通用寄存器传递.MOV R0,#12 ;调用 12 号软中断 MOV R1,#34 ;设置子功能号为 34SWI 0在 SWI 异常中断处理程序中,取出 SWI 立即数的步骤为:首先确定引起软中断的 SWI 指令是 ARM 指令还时 Thumb 指令,这可通过对 SPSR 访问得到:然后要取得该 SWI 指令的 地址,这可通过访问 LR 寄存器得到:接着读出指令,分解出立即数.读出 SWI 立即数T_bit EQU 0x20SWI_HanderSTMFD SP!,{R0_R3,R12,LR} ;现场保护 MRS R0,SPSR ;读取 SPSR STMFD SP!,{R0} ;保存 SPSRTST R0,#T_测试 T 标志位LDRNEH R0,[LR,#-2] ;若是 Thumb 指令,读取指令码(16 位) BICNE R0,R0,#0xFF00 ;取得 Thumb 指令的 8 位立即数LDREQ R0,[LR,#-4] ;若是 ARM 指令,读取指令码(32 位) BICNQ R0,R0,#0xFF00 ;取得 ARM 指令的 24 位立即数&LDMFD SP!,{R0-R3,R12,PC}^ ;SWI 异常中断返回XMRS读状态寄存器指令.在 ARM 处理器中,只有 MRS 指令可以状态寄存器 CPSR 或 SPSR 读出到通用寄存器中.指令格式如下;MRS{cond} Rd ,psr其中; Rd 目标寄存器.Rd 不允许为 R15. psr CPSR 或 SPSRSWI 指令举例如下MRS R1,CPSR ;将 CPSR 状态寄存器读取,保存到 R1 中MRS R2,SPSR ;将 SPSR 状态寄存器读取,保存到 R2 中MRS 指令读取 CPSR,可用来判断 ALU 的状态标志,或 IRQ,FIQ 中断是否允许等;在异 常处理程序中,读 SPSR 可知道进行异常前的处理器状态等.MRS 与 MSR 配合使用,实现 CPSR 或 SPSR 寄存器的读&修改写操作,可用来进行处理器模式切换(),允许?禁止 IRQ/FIQ 中断等设置.另外,进程切换或允许异常中断嵌套时,也需要使用 MRS 指令读取 SPSR 状态值.保存起来.使能 IRQ 中断 ENABLE_IRQMRS R0,CPSRBIC R0.R0,#0x80MSR CPSR_c,R0MOV PC,LR 禁能 IRQ 中断 DISABLE_IRQMRS R0,CPSRORR R0,R0,#0x80MSR CPSR_c,R0MOV PC,LRXMSR写状态寄存器指令.在 ARM 处理器中.只有 MSR 指令可以直接设置状态寄存器 CPSR 或 SPSR.指令格式如下MSR{cond} psr_fields,#immed_8rMSR{cond} psr_fields,Rm其中: psr CPSR 或 SPSRfields 指定传送的区域.Fields 可以是以下的一种或多种(字母必须为小写):c 控制域屏蔽字节(psr[7&0])x 扩展域屏蔽字节(psr[15&8])s 状态域屏蔽字节(psr[23.&16])f 标志域屏蔽字节(psr[31&24])immed_8r 要传送到状态寄存器指定域的立即数,8 位.Rm 要传送到状态寄存器指定域的数据的源寄存器. MSR 指令举例如下MSR CPSR_c,#0xD3 ;CPSR[7&0]=0xD3,即切换到管理模式. MSR CPSR_cxsf,R3 ;CPSR=R3 只有在特权模式下才能修改状态寄存器.程序中不能通过 MSR 指令直接修改 CPSR 中的 T 控制位来实现 ARM 状态/Thumb 状态 的切换,必须使用 BX 指令完成处理器状态的切换(因为 BX 指令属转移指令,它会打断流 水线状态,实现处理器状态切换).MRS 与 MSR 配合使用,实现 CPSR 或 SPSR 寄存器的读 修改写操作,可用来进行处理器模式切换、允许/禁止 IRQ/FIQ 中断等设置,.堆栈指令实始化 INITSTACKMOV R0,LR ;保存返回地址;设置管理模式堆栈MSR CPSR_c,#0xD3LDR SP,StackSvc;设置中断模式堆栈MSR CPSR_c,#0xD2LDR SP,StackIrq&ARM伪指令ARM 伪指令不是 ARM 指令集中的指令,只是为了编程方便编译器定义了伪指令,使用 时可以像其它 ARM 指令一样使用,但在编译时这些指令将被等效的 ARM 指令代替.ARM 伪 指令有四条,分别为 ADR 伪指令,ADRL 伪指令,LDR 伪指令,NOP 伪指令.XADR小范围的地址读取伪指令.ADR 指令将基于 PC 相对偏移的地址值读取到寄存器中. 在汇编编译源程序时,ADR 伪指令被编译器替换成一条合适的指令.通常,编译器用一条 ADD 指令或 SUB 指令来实现该 ADR 伪指令的功能,若不能用一条指令实现,则产生错误, 编译失败.ADR 伪指令格式如下 ADR{cond} register,exper其中 register 加载的目标寄存器exper 地址表达式.当地址值是非字地齐时,取值范围-255~255 字 节之间;当地址是字对齐时,取值范围- 字节之间. 对于基于 PC 相对偏移的地址值时,给定范围是相对当前指 令地址后两个字处(因为 ARM7TDMI 为三级流水线).ADR 伪指令举例如下;LOOP MOV R1,#0xF0&ADR R2,LOOP ;将 LOOP 的地址放入 R2ADR R3,LOOP+4 可以用 ADR 加载地址,实现查表:&ADR R0,DISP_TAB ;加载转换表地址LDRB R1,[R0,R2] ;使用 R2 作为参数,进行查表& DISP_TABDCB 0Xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90XADRL中等范围的地址读取伪指令.ADRL 指令将基于 PC 相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比 ADR 伪指令可以读取更大范围的地址。在汇编编译源程序时,ADRL 伪指令被编译器替换成两个条合适的指令。若不能用两条指令实现ADRL 伪指令功能,则产生错误,编译失败。ADRL 伪指令格式如下: ADR{cond} register,exper其中:register 加载的目标寄存器。expr 地址表达式。当地址值是非字对齐时,取范围-64K~64K 字节 之间;当地址值是字对齐时,取值范围-256K~256K 字节之间。ADRL 伪指令举例如下; ADRL R0,DATA_BUF&ADRL R1 DATA_BUF+80& DATA_BUFSPACE 100 ;定义 100 字节缓冲区可以且用 ADRL 加载地址,实现程序跳转,中等范围地址的加载&ADR LR,RETURNI ;设置返回地址ADRL R1 Thumb_Sub+1;取得了 Thumb 子程序入口地址,且 R1的0 位置1BX R1 ;调用 Thumb 子程序,并切换处理器状态 RETURNI& CODE16Thumb_SubMOV R1,#10&XLDR大范围的地址读取伪指令.LDR 伪指令用于加载 32 位的立即数或一个地址值到指定 寄存器.在汇编编译源程序时,LDR 伪指令被编译器替换成一条合适的指令.若加载的常 数未超出 MOV 或 MVN 的范围,则使用 MOV 或 MVN 指令代替该 LDR 伪指令,否则汇编器将常量放入字池,并使用一条程序相对偏移的 LDR 指令从文字池读出常量.LDR 伪指令格式如下;LDR{cond} register,=expr/label_expr其中 register 加载的目标寄存器expr 32 位立即数.label_expr 基于 PC 的地址表达式或外部表达式. LADR 伪指令举例如下.LDR R0,=0x123456 ;加载 32 位立即数 0xLDR R0,=DATA_BUF+60 ;加载 DATA_BUF 地址+60&LTORG ;声明文字池伪指令 LDR 常用于加载芯片外围功能部件的寄存器地址(32 位立即数),以实现各种 控制操作加载 32 位立即数&LDRR0,=IOPIN;加载 GPIO 寄存器 IOPIN 的地址LDRR1,[R0];读取 IOPIN 寄存器的值&LDRR0,=IOSETLDRR1,=0xSTRR1,[R0];IOSET=0x&从 PC 到文字池的偏移量必须小于 4KB与 ARM 指令的 LDR 相比,伪指令的 LDR 的参数有&=&号XNOP空操作伪指令.NOP 伪指令在汇编时将会被代替成 ARM 中的空操作,比如可能为 MOV,R0,R0 指令等,NOP 伪指令格式如下NOPNOP 可用于延时操作.软件延时& DELAY1NOPNOP NOPSUBS R1,R1,#1BNE DELAY1&Thumb指令集Thumb 指令可以看作是 ARM 指令压缩形式的子集,是针对代码密度的问题而提出 的,它具有 16 位的代码密度.Thumb 不是一个完整的体系结构,不能指望处理只执行 Thumb指令而不支持ARM指令集.因此,Thumb指令只需要支持通用功能,必要时可以借助 于完善的 ARM 指令集,比如,所有异常自动进入 ARM 状态.在编写 Thumb 指令时,先要使用伪指令 CODE16 声明,而且在 ARM 指令中要使用 BX 指令跳转到 Thumb 指令,以切换处理器状态.编写 ARM 指令时,则可使用伪指令 CODE32 声明.Thumb指令集与ARM指令集的区别Thumb 指令集没有协处理器指令,信号量指令以及访问 CPSR 或 SPSR 的指令,没有乘 加指令及 64 位乘法指令等,且指令的第二操作数受到限制;除了跳转指令 B 有条件执行 功能外,其它指令均为无条件执行;大多数 Thumb 数据处理指令采用 2 地址格式.Thumb 指令集与 ARM 指令的区别一般有如下几点:A 跳转指令程序相对转移,特别是条件跳转与 ARM 代码下的跳转相比,在范围上有更多的限制, 转向子程序是无条件的转移.A 数据处理指令 数据处理指令是对通用寄存器进行操作,在大多数情况下,操作的结果须放入其中一个操作数寄存器中,而不是第 3 个寄存器中.数据处理操作比 ARM 状态的更少,访问寄存器 R8~R15 受到一定限制.除 MOV 和 ADD 指令访问器 R8~R15 外,其它数据处理指令总是更新 CPSR 中的 ALU 状态标志. 访问寄存器 R8~R15 的 Thumb 数据处理指令不能更新 CPSR 中的 ALU 状态标志. A 单寄存器加载和存储指令在 Thumb 状态下,单寄存器加载和存储指令只能访问寄存器 R0~R7A 批量寄存器加载和存储指令LDM 和 STM 指令可以将任何范围为 R0~R7 的寄存器子集加载或存储.PUSH 和 POP 指令使用堆栈指令 R13 作为基址实现满递减堆栈.除 R0~R7 外,PUSH 指令还可以存储链接寄存器 R14,并且 POP 指令可以加载程序指令 PCThumb存储器访问指令Thumb 指令集的 LDM 和 SRM 指令可以将任何范围为 R0~R7 的寄存器子集加载或存储. 批量寄存器加载和存储指令只有 LDMIA,STMIA 指令,即每次传送先加载/存储数据,然后 地址加 4.对堆栈处理只能使用 PUSH 指令及 POP 指令.Thumb 存储器访问指令助记符说明 操作影响标志LDR Rd,[Rn,#immed_5&4]加载字数据Rd[Rm,#immed_5&4],Rd,Rn 为 R0~R7无LDRH Rd,[Rn,#immed_5&2]加载无符半字数据Rd[Rm,#immed_5&2],Rd,Rn 为 R0~R7无LDRB Rd,[Rn,#immed_5&1]加载无符字节数据Rd[Rm,#immed_5&1],Rd,Rn 为 R0~R7无STR Rd,[Rn,#immed_5&4]存储字数据Rn,#immed_5&4RdRd,Rn 为 R0~R7无STRH Rd,[Rn,#immed_5&2]存储无符半辽数据Rn,#immed_5&2]RdRd,Rn 为 R0~R7无STRB Rd,[Rn#immed_5&1]存储无符字节数据Rn,#immed_5&1]RdRd,Rn 为 R0~R7无LDR Rd,[Rn,Rm]加载字数据Rd[Rn,Rm],Rd,Rn,Rm 为 R0~R7无LDRH Rd,[Rn,Rm]加载无符半字数据Rd[Rn,Rm],Rd,Rn,Rm 为 R0~R7无LDRB Rd,[Rn,Rm]加载无符字节数据Rd[Rn,Rm],Rd,Rn,Rm 为 R0~R7无LDRSH Rd[Rn,Rm]加载有符半字数据Rd[Rn,Rm],Rd,Rn,Rm 为 R0~R7无LDRSB Rd[Rn,Rm]加载有符字节数据Rd[Rn,Rm],Rd,Rn,Rm 为 R0~R7无STR Rd,[Rn,Rm]存储字数据[Rn,Rm]Rd,Rd,Rn,Rm 为 R0~R7无STRH Rd,[Rn,Rm]存储无符半字数据[Rn,Rm]Rd,Rd,Rn,Rm 为 R0~R7无STRB Rd,[Rn,Rm]存储无符字节数据[Rn,Rm]Rd,Rd,Rn,Rm 为 R0~R7无LDR Rd,[PC,#immed_8&4]基于 PC 加载字数据Rd{PC,#immed_8&4]Rd 为 R0~R7无LDR Rd,label基于 PC 加载字数据Rd[label],Rd 为 R0~R7无LDR Rd,[SP,#immed_8&4]基于 SP 加载字数据Rd{SP,#immed_8&4]Rd 为 R0~R7无STR Rd,[SP,#immed_8&4]基于 SP 存储字数据{SP,#immed_8&4]Rd,Rd 为 R0~R7无LDMIA Rn{!}reglist批量(寄存器)加载regist[Rn&],Rn 回存等(R0~R7)无STMIA Rn{!}reglist批量(寄存器)加载[Rn&]reglist,Rn 回存等(R0~R7)无PUSH {reglist[,LR]}寄存器入栈指令[SP&]reglist[,LR],SP 回存等(R0~R7,LR)无POP {reglist[,PC]}寄存器入栈指令reglist[,PC][SP&],SP 回存等(R0~R7,PC)无XLDR和STR立即数偏移的LDR和STR指令.存储器的地址以一个寄存器的立即数偏移指明.指令 格式如下:LDR Rd,[Rn,#immed_5&4];加载指定地址上的数据(字),放入 Rd 中STR Rd,[Rn,#immed_5&4];存储数据(字)到指定地址的存储单元,要存储数据在 Rd 中 LDRH Rd,[Rn,#immed_5&4];加载半字数据,放入 Rd 中,即 Rd 低 16 位有效,高 16 位清零 STRH Rd,[Rn,#immed_5&4];存储半字数据,要存储的数据在 Rd,最低 16 位有效 LDRB Rd,[Rn,#immed_5&4];加载字节数据,放入 Rd 中,即 Rd 最低字节有效,高 24 位清零 STRB Rd,[Rn,#immed_5&4];存储字节数据,要存储的数据在 Rd,最低字节有效 其中 Rd 加载或存储的寄存器.必须为 R0~R7.Rn 基址寄存器.必须为 R0~R7.immed_5&N 偏移量.它是一个无符立即数表达式,其取值为(0~3)&N 立即数偏移的半字和字节加载是无符号的.数据加载到 Rd 的最低有效半字或字节,Rd 的其余位补 0.地址对准一一字传送时,必须保证传送地址为 32 位对准.半字传送时,必须保证传送地址为 16 位对准立即数偏移的 LDR 和 STR 指令举例如下; LDR R0,[R1,#0x4]STR R3,[R4]LDRH R5,[R0,#0x02] STRH R1,[R0,#0x08] LDRB R3,[R6,#20] STRB R1,[R0,#31]寄存器偏移的 LDR 和 STR 指令.存储器的地址用一个寄存器的基于寄存器偏移来指明.指令格式如下,LDRRd,[Rn,Rm];加载一个字数据STRRd,[Rn,Rm];存储一个字数据LDRHRd,[Rn,Rm];加载一个无符半字数据STRHRd,[Rn,Rm];存储一个无符半字数据LDRBRd,[Rn,Rm];加载一个无符字节数据STRBRd,[Rn,Rm];存储一个无符字节数据LDRSHRd,[Rn,Rm];加载一个有符半字数据LDRSBRd,[Rn,Rm];存储一个有符半字数据其中:Rd加载或存储的寄存器.必须为 R0~R7Rn基址寄存器.必须为 R0~R7Rm内含偏移量的寄存器.必须为 R0~R7.寄存器偏移的半字和字节加载可以是有符号或无符号的,数据加载到 Rd 的其余位 拷贝符号位.地址对准&字传送时,必须保证传送地址为 32 位对准.半字传送时,必须保证传送 地址为 16 位对准.寄存器偏移的 LDR 和 STR 指令举例如下; LDR R3,[R1,R0]STR R1,[R0,R2] LDRH R6,[R0,R1] STRH R0,[R4,R5] LDRB R2,[R5,R1] STRB R1,[R3,R2] LDRSH R7,[R6,R3] LDRSB R5,[R7,R2]PC 或 SP 相对偏移的 LDR 和 STR 指令.用 PC 或 SP 寄存器中的值的立即数偏移来指 明存储器的地址.指令格式如下.LDR Rd,[PC,#immed_8&4] LDR Rd,labelLDR Rd,[SP,#immed_8&4] STR Rd,[SP,#immed_8&4]其中: Rd 加载或存储的寄存器.必须为 R0~R7immed_8&4] 偏移量.它是一个无符立即数表达式,其取值为(0~255)&4label 程序相对偏移表达式.label 必须在当前指令之后 IK 字节范围内.地址对准&地址必须是 4 的整数倍.PC 或 SP 相对偏移的 LDR 和 STR 指令举例如下;LDRR0,[PC,#0x08];读取 PC+0x08 地址上的字数据,保存到 R0 中LDRR7,LOCALDAT;读取 LOCALDAT 地址上的字数据,保存到 R7 中LDRR3,[SP,#1020];读取 SP+1020 地址上的字数据,保存到 R3 中STRR2,[SP];存储 R2 寄存器的数据到 SP 指向的存储单元(偏移量为 0)XPUSH和POP寄存器入栈及出栈指令.实现低寄存器和可选的 LR 寄存器入栈寄存器和可选的 PC 寄存器出栈操作,堆栈地址由 SP 寄存设置,堆栈是满递减堆栈.指令格式如下;PUSH {reglist[,LR]}POP {reglist[,PC]}其中reglist入栈/出栈低寄存器列表,即 R0~R7LR入栈时的可选寄存器PC出栈时的可选寄存器寄存器入栈及出栈指令举例如下;PUSH{R0-R7,LR};将低寄存器 R0~R7 全部入栈,LR 也入栈POP{R0-R7,PC};将堆栈中的数据弹出到低寄存器 R0~R7 及 PC 中XLDMIA和STMIA批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数 据.Thumb 指令集批量加载/存储指令为 LDMIA 和 STMIA,LDMIA 为加载多个寄存器;STM 为存储多个寄存器,允许一条指令传送 8 个低寄存器的任何子集.指令格式如下;LDMIA Rn!,reglistSTMIA Rn!,reglist其中 Rn 加载/存储的起始地址寄存器.Rn 必须为 R0~R7Reglist 加载/存储的寄存器列表.寄存器必须为 R0~R7LDMIA/STMIA 的主要用途是数据,参数传送等,进行数据传送时,每次传送后地址加 4.若 Rn 在寄存器列表中,对于 LDMIA 指令,Rn 的最终值是加载的值,而不是增加后的地址;对于 STMIA 指令,在 Rn 是寄存器列表中的最低数字的寄存器,则 Rn 存储的值为 Rn 在初值,其它情况不可预知.批量加载/存储指令举例如下;LDMIA R0,{R2-R7} ;加载 R0 指向的地址上的多字数据,保存到 R2~R7 中,R0 的值更新.STMIA R1!,{R2-R7};将 R2~R7 的数据存储到 R1 指向的地址上,R1 值更新.Thumb数据处理指令大多数 Thumb 处理指令采用 2 地址格式,数据处理操作比 ARM 状态的更少,访问寄存 器 R8~R15 受到一定限制.Thumb 数据处理指令助记符说明操作影响标志MOV Rd,#expr数据转送Rdexpr,Rd 为 R0~R7影响 N,ZMOV Rd,Rm数据转送RdRm,Rd、Rm 均可为 R0~R15RdT 和 Rm 均 为R0~ R7 时,影响 N,Z,清零 C,VMVN Rd,Rm数据非传送指令Rd(~Rm),Rd,Rm 均为 R0~R7影响 N,ZNEG Rd,Rm数据取负指令Rd(-Rm),Rd,Rm 均为 R0~R7影响 N,Z,C,VADD Rd.Rn,Rm加法运算指令RdRn+Rm,Rd,Rn,Rm 均为 R0~R7影响 N,Z,C,VADD Rd.Rn,#expr3加法运算指令RdRn+expr#,Rd,Rn 均为 R0~R7影响 N,Z,C,VADD Rd,#expr8加法运算指令RdRd+expr8,Rd 为 R0~R7影响 N,Z,C,VADD Rd,Rm加法运算指令RdRd+Rm,Rd,Rm 均可为 R0~R15Rd和 Rm 均为 R0~R7 时 , 影 响 N,Z,C,VADD Rd,Rp#exprSP/PC 加法运算指令RdSP+expr 或 PC+expr,Rd 为 R0~R7无ADD SP,#exprSP 加法运算指令SPSP+expr无SUB Rd,Rn,Rm减法运算指令RdRn-Rm,Rd、Rn、Rm 均为 R0~R7影响 N,Z,C,VSUB Rd,Rn#expr3减法运算指令RdRn-expr3,RdRn 均为 R0~R7影响 N,Z,C,VSUB Rd,#expr8减法运算指令RDRd-expr8,Rd 为 R0~R7影响 N,Z,C,VSUB SP,#exprSP 减法运算指令SPSP-expr无ADC Rd,Rm带进位加法指令RdRd+Rm+Carry,Rd、Rm 为 R0~R7影响 N,Z,C,VSBC Rd,Rm带位减法指令RdRd-Rm-(NOT)Carry,Rd、Rm 为 R0~R7影响 N,Z,C,VMUL Rd,Rm乘法运算指令RdRd*Rm,Rd、Rm 为 R0~R7影响 N,Z,AND Rd,Rm逻辑与操作指令RdRd&Rm,Rd、Rm 为 R0~R7影响 N,Z,ORR Rd,Rm逻辑或操作指令RdRdRm,Rd、Rm 为 R0~R7影响 N,Z,EOR Rd,Rm逻辑异或操作指令RdRd^Rm,Rd、Rm 为 R0~R7影响 N,Z,BIC Rd,Rm位清除指令RdRd&(~Rm),Rd、Rm 为 R0~R7影响 N,Z,ASR Rd,Rs算术右移指令RdRd 算术右移 Rs 位,Rd,Rs 为 R0~R7影响 N,Z,C,ASR Rd,Rm#expr算术右移指令RdRm 算术右移 expr 位,Rd、Rm 为 R0~R7影响 N,Z,C,LSL Rd,Rs逻辑左移指令RdRd<<Rs,Rd、Rs 为 R0~R7影响 N,Z,C,LSL Rd,Rm,#expr逻辑左移指令RdRm<<expr,Rd、Rm 为 R0~R7影响 N,Z,C,LSR Rd,Rs逻辑右移指令RdRd>>Rs,Rd、Rs 为 R0~R7影响 N,Z,C,LSR Rd,Rm,#expr逻辑右移指令RdRm>>mexpr,Rd、Rm 为 R0~R7影响 N,Z,C,ROR Rd,Rs循环右移指令RdRm 循环右移 Rs 位,Rd、Rs 为 R0~R7影响 N,Z,C,CMP Rn,Rm比较指令状态标Rn-Rm,Rn、Rm 为 R0~R15影响 N,Z,C,VCMP Rn,#expr比较指令状态标Rn-expr,Rn 为 R0~R7影响 N,Z,C,VCMN Rn,Rm负数比较指令]状态标Rn+Rm,Rn、Rm 为 R0~R7影响 N,Z,C,VTST Rn,Rm 位测试指令 状态标Rn&Rm,Rn、Rm 为 R0~R7 影响 N,Z,C,V数据传送指令XMOV数据传送指令.将 8 位立即数或寄存器(operand2)传送到目标寄存器(Rd).指令格 式如下;MOV Rd,#exprMOV Rd,Rm其中 Rd 目标寄存器.MOV Rd#expr 时,必须在 R0~R7 之间exper 8 位立即数,即 0~255Rm 源寄存器.为 R0~R15 条件码标志:MOV Rd,#expr 指令会更新N和Z 标志,对标志C和V 无影响.而 MOV,Rd,Rm 指令,若 Rd 或 Rm 是高寄存器(R8~R15),则标志不受影响,若 Rd 或 Rm 都是低寄存器(R0~R7),则会更新 N 和 Z,且清除标志C和 V.MOV 指令举例如下MOVR1,#0x10;R1=0x10MOVR0,R8;R0=R8MOVPC,LR;PC=LR,子程序返回XMVN数据非传送指令.将寄存器 Rm 按位取反后传送到目标寄存器(Rd).指令格式如下: MVN Rd,Rm其中: Rd 目标寄存器.必须在 R0~R7 之间 Rm 源寄存器.必须在 R0~R7 之间条件码标志:指令会更新N和Z 标志,对标志C和V 无影响. MVN 指令举例如下MVN R1,R2 ;将 R2 取反结果存到 R1XNEG数据取负指令.将寄存器 Rm 乘以-1 后传送到目标寄存器(Rd).指令格式如下: NEG Rd,Rm其中: Rd 目标寄存器.必须在 R0~R7 之间 Rm 源寄存器.必须在 R0~R7 之间条件码标志指令会更新 N,Z,C,V 和标志. NEG 指令举例如下NEG R1,R0, ;R1=-R0算术逻辑运算指令XADD加法运算指令.将两个数据相加,结果保存到 Rd 寄存器. 低寄存器的 ADD 指令的指令格式如下ADD Rd,Rn,RmADD Rd,Rn,#expr3ADD Rd,#expr8其中 Rd 目标寄存器.必须在 R0~R7 之间.Rn 第一个操作数寄存器.必须在 R0~R7 之间. Rm 第二个操作数寄存器.必须在 R0~R7 之间. expr3 3 位立即数,即 0~7expr8 8 位立即数,即 0~255. 条件码标志:指令会更新 N、Z、C 和 V 标志. 高或低寄存器的 ADD 指令的指令格式如下: ADD Rd,Rm其中 Rd 目标寄存器,也是第一个操数寄存器.Rm 第二个操作数寄存器条件码标志:若 Rd 或 Rm 都是低寄存器(R0~R7),指令会更新 N、Z、C 和 V 标志.其它 情况不影响条件码标志.PC 或 SP 相对偏移的 ADD 指令指令格式如下:ADD Rd,Rp,#expr其中 Rd 目标寄存器.必须在 R0~R7 之间 Rp PC 或 SP,第一个操作数寄存器. expr 立即数,在 0~1020 范围内.条件码标志:不影响条件码标志.SP 操作的 ADD 指令的指令格式如下 ADD SP,#exprADD SP,SP,#expr其中 SP 目标寄存器,也是第一个操作数寄存器.expr 立即数,在-508~+508 之间的 4 的整数倍的数条件码标志:不影响条件码标志.ADD 指令举例如下ADD R1,R1,R0 ;R1=R1+R0ADD R1,R1,#7 ;R1=R1+7ADD R3,#200 ;R3=R3+200ADD R3,R8 ;R3=R3+R8ADD R1,SP,#1 ;R1=SP+1ADD SP,SP,#-500 ;SP=SP-500XSUB减法运算指令.将两个数相减,结果保存到 Rd 中. 低寄存器的 SUB 指令的指令格式如下;SUB Rd,Rn,RmSUB Rd,Rn,#expr3SUB Rd,#expr8其中Rd目标寄存器.必须在 R0~R7 之间Rn第一个操作数寄存器.必须在 R0~R7 之间Rm第一个操作数寄存器.必须在 R0~R7 之间expr33 位立即数,即 0~7expr8 8 位立即数.即 0~255条件码标志:指令会更新 N、Z、C 和 V 标志. SP 操作的 SUB 指令的指令格式如下SUB SP,#exprSUB SP,SP,#expr其中 SP 目标寄存器,也是第一个操作数据寄存器. expr 立即数,在-508~+508 之间的 4 的整数倍的数条件码标志:不影响条件码标志SUB 指令举例如下SUBR0,R2,R1,;R0=R2-R1SUBR2,R1,#1;R2=R1-1SUBR6,#250;R6=R6-250SUBSP,#380;SP=SP-380XADC带进位加法指令.将 Rm 的值与 Rd 的值相加,再加上 CPSR 中的 C 条件标志位,结果保 存到 Rd 寄存器.指令格式如下ADC Rd,Rm其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rm 第二个操作数寄存器.必须在 R0~R7 之间条件码标志:指令会更新 N、Z、C 和 V 标志. ADC 指令举例如下;ADD R0,R0,R2,ADC R1,R1,R3 ;使用 ADC 实现 64 位加法,(R1,R0)+(R3,R2)XSBC带进位减法指令.用寄存器 Rd 减去 Rm,再减去 CPSR 中的 C 条件标志的非(即若 C 标 志清零,则结果减去 1),结果保存到 Rd 中.指令格式如下SBC Rd,Rm其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间Rm 第二个操作数寄存器.必须在 R0~R7 之间]条件码标志:指令会更新 N、Z、C和V 标志 SBC 指令举例如下SUB R0,R0,R2SUB R1,R1,R3 ;使用 SBC 实现 64 位减法,(R1,R0)=(R1,R0)-(R3,R2)XMUL乘法运算指令.用寄存器 Rd 乘以 Rm,结果保存到 Rd 中.指令格式如下; MUL Rd,Rm其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rm 第二操作数寄存器.必须在 R0~R7 之间条件码标志:指令会更新N和Z 标志 MUL 指令举例如下MUL R2,R0,R1 ;R2=R0*R1XAND逻辑与操作指令.将寄存器 Rd 的值与寄存器 Rm 值按位作逻辑与操作,结果保存到 Rd 中.指令格式如下AND Rd,Rm其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rm 第二个操作数寄存器.必须在 R0~R7 之间条件码标志:指令会更新N和Z 标志 AND 指令举例如下;MOV R1,#0x0FAND R0,R1 ;R0=R0 & R1XORR逻辑或操作指令.将寄存器 Rd 与寄存器 Rn 的值按位作逻辑或操作,结果保存到 Rd中.指令格式如下:ORRRd,Rm其中Rd目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间Rm 第二个操作数寄存器.必须在 R0~R7 之间条件码标志:指令会更新N和Z 标志 ORR 指令举例如下MOVR1,#0x03ORRR0,R1;R0=R0R1XEOR逻辑异或操作指令.寄存器Rd的值与寄存器Rn的值按位作逻辑异或操作,结果保存 到 Rd 中,指令格式如下;EOR Rd,Rm其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rm 第二个操作数寄存器.必须在 R0~R7 之间条件码标志:指令会更新N和Z 标志EOR 指令举例如下MOVR2,#0Xf0EORR3,R2,;R3=R3^R2XBIC位清除指令.将寄存器Rd的值与寄存器Rm的值反码按位作逻辑与操作.结果保存到 Rd 中,指令格式如下BIC Rd,Rm其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间.Rm 第二个操作数寄存器.必须在 R0~R7 之间条件码标志:指令会更新N和Z 标志BIC 指令举例如下:MOVR1,#0x80BICR3,R1;将 R1 的最高位清零,其它位不变XASR算术右移指令.数据算术右移,将符号位拷贝到空位,移位结果保存到 Rd 中,指令格 式如下;ASR Rd,RsASR Rd,Rm,#expr其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rs 寄存器控制移位中包含移位量的寄存器.必须在 R0~R7 之间 Rm 立即数移位的源寄存器.必须在 R0~R7 之间expr 立即数移位量,值为 1~32条件码标志:指令会更新 N、Z 和 C 标志(若移位量为零,则不影响 C 标志) ASR 指令举例如下ASR R1,R2, ASR R3,R1,#2若移位量为 32,则 Rd 清零,最后移出的位保留在标志 C 中,若移位量大于 32,则 Rd和标志 C 均被清零;若移位量为 0,则不影响 C 标志XLSL逻辑左移指令.数据逻辑左移,空位清零,移位结果保存到 Rd 中,指令格式如下 LSL Rd,RsLSL Rd,Rm,#expr其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rs 寄存器控制移位中包含位量的寄存器.必须在 R0~R7 之间 Rm 立即数移位的源寄存器.必须在 R0~R7 之间expr 立即数移位量,值为 1~31条件码标志:指令会更新 N、Z 和 C 标志(若移位量为零,则不影响 C 标志) LSL 指令举例如下LSL R6,R7LSL R1,R6,#2若移位量为 32,则 Rd 清零,最后移出的位保留在标志 C 中;若移位量大于 32,则 Rd和标志 C 均被清零;若移位量为 0,则不影响 C 标志XLSR逻辑左移指令.数据逻辑左移,空位清零,移位结果保存到 Rd 中.指令格式如下LSR Rd,RsLSR Rd,Rm,#expr其中 Rd 目标寄存器,也是第一个操作数寄存器.必须在 R0~R7 之间 Rs 寄存器控制移位中包含移位量的寄存器.必须在 R0~R7 之间 Rm 立即数移位的源寄存器.必须在 R0~R7 之间expr 立即数移位量,值为 1~32条件码标志:指令会更新 N、Z 和 C 标志(若移位量为零,则不影响 C 标志) LSR 指令举例如下LSR R3,R0LSR R5,R2,#2若移位量为 32,则 Rd 清零,最后移出的位保留在标志 C 中;若移位量大于 32,则 Rd和标志 C 均被清零,若移位量为 0,则不影响 C 标志.XROR循环右移指令.数据循环右移,寄存器右边移出的位循环移回到左边,移位结果保存 到 Rd 中,指令格式如下ROR Rd,Rs其中 Rd 目标寄存器.也是第一个操作数寄存器.必须在 R0~R7 之间 Rs 寄存器控制移位中包含移位量的寄存器.必须在 R0~R7 之间条件标志:指令会更新 N,Z,C 的标志(若移位量为零,则不影响 C 标志). ROR 指令举例如下ROR R2,R3比较指令XCMP比较指令.指令使用寄存器 Rn 的值减去第二个操作数的值,根据操作的结果理新 CPSR 中的相应条件标志位.指令格式如下CMP Rn,RmCMP Rn,#expr其中Rn第一个操作数寄存器.对 CMP,Rn#expr 指令,Rn 在 R0~R7 之间;对于CMP,Rn,Rm 指令在 Rn 在 R0~R15 之间Rm第二个操作数寄存器.Rm 在 R0~R15 之间expr立即数,值为 0~255条件码标志:指令会更新 N、Z、C和V 标志 CMP 指令举例如下CMP R1,#10 ;R1 与 10 比较,设置相关标志位 CMP R1,R2 ;R1 与 R2 比较,设置相关标志位XCMN负数比较指令.指令使用寄存器 Rn 的值加上寄存器 Rm 的值,根据操作的结果理新 CPSR 中的相应条件标志.位指令格式如下CMN Rn,Rm其中 Rn 第一个操作数寄存器,必须在 R0~R7 之间 Rm 第二个操作数寄存器.必须在 R0~R7 之间条件码标志:指令会更新 N、Z、C 和 V 标志. CMN 指令举例如下CMM R0,R2 ;R0 与 R2 进行比较XTST位测试指令.指令将寄存器Rn的值与寄存器Rm的值按位作逻辑与操作.根据操作的 结果理新 CPSR 相应条件标志位.指令格式如下.TST Rn,Rm其中 Rn 第一个操作数寄存器.必须在 R0~R7 之间 Rm 第二个操作数寄存器.必须在 R0~R7 之间条件码标志:指令会更新 N、Z、C和V 标志 TST 指令举例如下MOV R0,#x01TST R1,R0, ;判断 R1 的最低位是否为 0Thumb跳转指令助记符说明操作条件码位置B label跳转指令PClabelB{cond}BL label带链接的跳转指令LRPC4,PClabel无BX Rm带状态切换的跳转指令PClabel 切换处理器状态无XB跳转指令.跳转到指定的地址执行程序.这是 Thumb 指令集中的惟一的有条件执行 指令.指令格式如下B{cond} label 跳转指令 B 举例如下 B WAITBBEQ LOOP1若使用 cond 则 label 必须在当前指令的-252~+256 字节范围内;若指令是无条件的, 则跳转指令 label 必须在当前指令的&2K 字节范围内XBL带链接的跳转指令.指令先将下一条指令的地址拷贝到 R14(即 LR)链接寄存器中, 然后跳转到指定地址运行程序.指令格式如下:BL label带链接的跳转指令 BL 举例如下 BL DELAYI机器级转指令 BL 限制在当前指令的&4Mb 的范围内.(必要时,ARM 链接器插入代码 以允许更长的转移.)XBX带状态切换的跳转指令.跳转到 Rm 指定的地址执行程序.若 Rm 的位[0]为 0,则 Rm 的位于也必须为 0,跳转时自动将 CPSR 中的标志 T 复位,即把目标地址的代码解释为 ARM 代码.指令格式BX Rm带状态切换的跳转指令 BX 举例如下.ADR R0,ArmFunBX R0 ;跳转到R0指定的地址,并根据R0的最低位来切换处理器状态.Thumb杂项指令XSWI软中断指令.SWI 指令用于产生软中断,从而实现在用户模式变换到管理模式.CPSR 保存到管理模式的 SPSR 中,执行转移到 SWI 向量.在其它模式下也可使用 SWI 指令,处理 器同样地切换到管理模式.指令格式如下. SWI immed_8其中 immed_8 8 位立即数,值为 0~255 之间的整数. SWI 指令举例如下SWI 1 ;软中断,中断立即数为 0SWI 0x55 ;软中断,中断立即数为 0x55使用 SWI 指令时,通常使用以下两种方法进行传递参数,SWI 异常中断处理程序可以 提供相关的服务,这两种方法均是用户软件协定.SWI 异常中断处理程序要通过读取引 起软中断的 SWI 指令.以取得 8 位立即数.1.指令中 8 位的立即数指定了用户请求的服务类型,参数通过用寄存器传递. MOV R0,#34 ;设置子功能号为虎作 34SWI 18 ;调用 18 号软中断2.指令中的 8 位立即数被忽略,用户请求的服务类型由寄存器 R0 的值决定,参数通 过其它的通用寄存器传递.MOV R0,#18 ;调用 18 号软中断 MOV R1,#34 ;设置子功能号为了 4SWI 0Thumb伪指令XADR小范围的地址读取伪指令.ADR 指令将基于 PC 相对偏移的地址值读取到寄存器 中.ADR 伪指令格式如下.ADR register,expr其中 register 加载的目标寄存器.expr 地址表达式.偏移量必须是正数并小于 1KB.Expr 必须局部定义, 不能被导入.ADR 伪指令举例如下ADR register, expr其中 register 加载的目标寄存器。expr 地址表达式。偏移量必须是正数并小说于 1KB。Expr 必须局部 定义,不能被导入。ADR 伪指令举例如下: ADR R0,TxtTab& TxtTabDCB &ARM7TDMI&,0XLDR大范围的地址读取伪指令.LDR 伪指令用于加载 32 位的立即数或一个地址值到指定 寄存器.在汇编编译源程序时,LDR 伪指令被编译器替换成一条合适的指令.若加载的常 数未超出 MOV 范围,则使用 MOV 或 MVN 指令代替 LDR 伪指令,否则汇编器将常量放入文字 池,并使用一条程序相对偏移的 LDR 指令从文字池读出常量.LDR 伪指令格式如下.LDR register,=expr/label_expr其中, register 加载的目标寄存器expr 32 位立即数.label_expr 基于 PC 的地址表达式或外部表达式. LADR 伪指令举例如下;LDR R0,=0x ;加载 32 位立即数 0xLDR R0,=DATA_BUF+60 ;加载 DATA_BUF 地址+60&LTORG ;声明文字池&从 PC 到文字池的偏移量必须是正数小于是 1KB.与 Thumb 指令的 LDR 相比,伪指令的 LDR 的参数有&=&号.XNOP空操作伪指令.NOP 伪指令在汇编时将会将会被代替成 ARM 中的空操作,比如可能为 MOV,R8,R8 指令等.NOP 伪指令格式如下.NOPNOP 可用于延进操作伪指令ARM 汇编程序的由机器指令,伪指令和宏指令组成.伪指令不像机器指令那样在处 理器运行期间由机器执行,而是汇编程序对源程序汇编期间由汇编程序处理.在前面的 指令集章节中,我们已经接触了几条常用到的伪指令,如 ADR ,ADRL,LDR,NOP 等,把它们 和指令集一起介绍是因为它们在汇编时会被合适的机器指令代替,实现真正机器指令操 作.宏是一段独立的程序代码,它是通过伪指令定义的,在程序中使用宏指令即可调用宏. 当程序被汇编时,汇编程序将对每个调用进行展开,用宏定义取代源程序中的宏指令.符号定义伪指令符号定义伪指令用于定义 ARM 汇编程序的变量,对变量进行赋值以及定义寄存器名 称,该类伪指令如下;全局变量声明:GBLA,GBLL 和 GBLS 局部变量声明:LCLA,LCLL 和 LCLS 变量赋值: SETA,SETL 和 SETS 为一个通用寄存器列表定义名称:RLIST 为一个协处理器的寄存器定义名称:CN 为一个协处理定义名称: CP为一个 VFP 寄存器定义名称:DN 和 SN 为一个 FPA 浮点寄存器定义名称:FNXGBLA、GBLL、GBLS全局变量声明伪指令.GBLA 伪指令用于声明一个全局的算术变量,并将其初始化为 0;GBLL 伪指令用于声明一个全局的逻辑变量,并将其初始化为{FALSE};GBLS 伪指令用于声明一个全局的字符串变量,并将其初始化为空字符串&&。 伪指令格式;GBLA variableGBLLvariableGBLSvariable其中variable定义的全局变量名,在其作用范围内必须惟一.全局变量的作用范围为包含该变量的源程序. 伪指令应用举例如下;GBLL声明一个全局逻辑变量codebg SETL {TRUE} ;设置变量为{TRUE}&XLCLA、LCLL、LCLS局部变量声明伪指令.用于宏定义的体中.LCLA 伪指令用于声明一个局部的算术变量,并将其初始化为 0LCLL 伪指令用于声明一个局部的逻辑变量,并将其初始化为{FALSE}LCLS 伪指令用于声明一个局部的字符串变量,并将其初始化为空字符串&& 伪指令格式;LCLA variable LCLL variable LCLS variable其中 variable 定义的局部变量名。在其作用范围内必须惟一。局部变量的作用范围为包含该局部变量只能在宏中进行声明及使用。伪指令应用举例如下;MACRO ;声明一个宏 SENDDAT $宏的原型LCLA声明一个局部算术变量&bitno SETA 8 ;设置变量值为 8& MENDXSETA、SETL、SETS变量赋值伪指令.用于对已定义的全局变量,局部变量赋值. SETA 伪指令用于给一个全局/局部的算术变量赋值.SETL 伪指令用于给一个全局/局部的逻辑变量赋值. SETS 伪指令用于给一个全局/局部的字符串变量赋值. 伪指令格式;variable_a SETA expr_a variable_l SETL expr_lvariable_s SETS expr_s其中variable_a算术变量.用 GBLA,LCLA 伪指令定义的变量.expr_a赋值的常数.variable_l逻辑变量.用 GBLL,LCLL 伪指令定义的变量.expr_l逻辑值,即{TRUE}或{FALSE}.variable_s字符串变量.用 GBLS,LCLS 伪指令定义的变量.expr_s赋值的字符串.伪指令应用举例如下.GBLS ErrStr&ErrStr SETS &No,semaphone&&XRLISTRLIST 为一个通用寄存器列表定义名称.伪指令格式如下:name RLIST {reglist}其中 name 要定义的寄存器列表的名称. reglist 通用寄存器列表.伪指令应用举例如下;LoReg RLIST {R0-R7} ;定义寄存器列表 LoReg&STMFD SP!,LoR保存寄存器列表 LoReg&XCNCN 为一个协处理器的寄存器定义名称. 伪指令格式;name CN expr其中 name 要定义的协处理器的寄存器名称.expr 协处理器的寄存器编号,数值范围为 0~15. 伪指令应用举例如下;MemSet CN将协处理的寄存器 l 名称定义为 MemSetXCPCP 为一个协处理器定义的名称. 伪指令格式;name CP expr其中 name 要定义的协处理器名称.expr 协处理器的编号,数值范围为 0~15. 伪指令应用举例如下;DivRun CN 5 ;将协处理器 5 名称定义为 DivRunXDN、SNDN 和 SN 为 VFP 的寄存器的名称定义的伪指令. DN 为一个双精度原 VFP 寄存器定义名称.SN 为一个单精度的 VFP 寄存器定义名称. 伪指令格式;name DN exprname SN expr其中 name 要定义的 VFP 寄存器名称.expr 双精度的 VFP 寄存器编号为 0~15,单精度的 VFP 寄存器编号为 0~31. 伪指令应用举例如下;cdn DN 1 ;将 VFP 双精度寄存器 1 名称定义为 cdn rex SN 3 ;将 VFP 单精度寄存器 3 名称定义为 rexXFNFN 为一个 FPA 浮点寄存器定义名称 伪指令格式;name FN expr其中 name 要定义的浮点寄存器名称. expr 浮点寄存器的编号,值为 0~7伪指令应用举例如下;ibq FN将浮点寄存器 l 名称定义为 ibq数据定义伪指令数据定义伪指令用于数据表定义,文字池定义,数据空间分配等.该类伪指令如下; 声明一个文字池:LTORG;定义一个结构化的内存表的首地址:MAP 定义结构化内存表中的一个数据域:FIELD 分配一块内存空间,并用 0 初始化:SPACE 分配一段字节的内存单元,并用指定的数据初始化:DCB; 分配一段字的内存单元,并用指令的数据初始化:DCD 和 DCDU;分配一段字的内存单元,将每个单元的内容初始化为该单元相对于静态基址寄存器的偏移量:DCDO;分配一段双字的内存单元,并用双精度的浮点数据初始化:DCFD 和 DCFDU; 分配一段字的内存单元,并用单精度的浮点数据初始化:DCFS 和 DCFSU;分配一段字的内存单元,并用单精度的浮点数据初始化,指定内存单元存放的是代码,而不是数据:DCI分配一段双字的内存单元,并用 64 位整数数据初始化:DCQ 和 DCQU 分配一段半字的内存单元,并用指定的数据初始化:DCW 和 DCWU;XLTORGLTORG 用于声明一个文字池,在使用 LDR 伪指令时,要在适当的地址加入 LTORG 声明 文字池,这样就会把要加载的数据保存在文字池内,再用 ARM 的加载指令读出数据.(若没有使用 LTORG 声明文字池,则汇编器会在程序末尾自动声明.)伪指令格式:LTORG伪指令应用举例如下;&LDR R0,=0xADD R1,R1,R0MOV PC,LRLTORG ;声明文字池,此地址存储 0x& ;其它代码LTORG 伪指令常放在无条件跳转指令之后,或者子程序返回指令之后,这样处理器 就不会错误地将文字池中的数据当作指令来执行.XMAPMAP 用于定义一个结构化的内存表的首地址.此时,内存表的位置计数器{VAR}设置 为该地址值{VAR}为汇编器的内置变量.^与 MAP 同义.伪指令格式:MAP expr,{base_register}其中 expr 数字表达式或程序中的标号.当指令中没有base_register 时,expr 即为结构化内存表的首地址.base_register 一个寄存器.当指令中包含这一项时,结构化内存表的首地址为 expr 与 base_register 寄存器值的和.伪指令应用举例如下;MAP 0x00,R9 ;定义内存表的首地址为 R9Timer FIELD 4 ;定义数据域 Timer,长度为 4 字节 Attrib FIELD 4 ;定义数据域 Attrib,长度为 4 字节 String FIELD 100 ;定义数据域 String,长度为 100 字节&ADR R9,DataS设置 R9 的值,即设置结构化的内存表地址 LDR R0,A相当于 LDR,R0,[R9,#4]&MAP 伪指令和 FIELD 伪指令配合使用,用于定义结构化的内存表结构.MAP 伪指令中 的base-register寄存器的值对于其后所有的FIELD伪指令定义的数据域是默认使用的, 直到遇到新的包含 base-register 项的 MAP 伪指令.XFIELDFIELD 用于定义一个结构化内存表中的数据域.#与 FIELD 同义. 伪指令格式:{tabel}FIELDexpr其中label当指令中包含这一项时,label 的值为当前内存表的位置计数器{VAR}的值,汇编编译器处理了这条 FIELD 伪指令后,内存表计数器的值将加上 expr.expr表示本数据域在内存表中所占用的字节数.伪指令应用举例如下;MAP0x43;内存表的首地址为 0x43count1FIELD4;定义数据域 count1,长度为 4 字节count2FIELD4;定义数据域 count2,长度为 4 字节count3FIELD4;定义数据域 count3,长度为 4 字节&LDRR1,count1;R1=[0x43+0x00]STRR1,count2;[0x43+0x00]=R1MAP,FIELD 伪指令仅仅是定义数据结构,它们并不实际分配内存单元.XSPACESPACE 用于分配一块内存单元,并用 0 初始化.%与 SPACE 同义. 伪指令格式:{label} SPACE expr其中 label 内存块起始地址标号. expr 所要分配的内存字节数.伪指令应用举例如下;AREA DataRA,DATA,READWROTE ;声明一数据段,名为 DataRAM DataBuf SPACE 1 ;分配 1 字节空间XDCBDCB 用于分配一段字节内存单元,并用伪指令中的 expr 初始化.一般可用来定义数 据表格,或文字符串.=与 DCB 同义.伪指令格式:{label} DCB expr{,expr}{,expr}& 其中 label 内存块起始地址标号.expr 可以为-128~255 的数值或字符串.内存分配的字节数由 expr 个数决定.伪指令应用举例如下DISPTAB DCB 0x33,0x43,0x76,0x12DCB -120,20,36,55ERRSTR DCB &Send,data is error!&,0XDCD和DCDUDCD用于分配一段字内存单元,并用伪指令中的expr初始化.DCD伪指令分配的内存 需要字对齐,一般可用来定义数据表格或其它常数.&与 DCD 同义.DCDU 用于分配一段字内存单元,并用伪指令中的 expr 初始化.DCD 伪指令分配的内 存不需要字对齐,一般可用来定义数据表格或其它常数.伪指令格式:{label} DCD expr{,expr}{,expr}&{label} DCDU expr{,expr}{,expr}& 其中 label 内存块起始地址标号.expr 常数表达式或程序中的标号.内存分配字节数由 expr 个数决定. 伪指令应用举例如下:VectorsLDR PC,ReserAddrLDR PC,UndefinedAddr&ResetAddr DCD ResetUndefinedAddr DCD Undefined&Reset&Undefined&XDCDODCDO 用于分配一段字内存单元.并将每个单元的内容初始化为该单元相对于静态基址寄存器的偏移量.DCDO 伪指令作为基于静态基址寄存器 R9 的偏移量分配内存单 元.DCDO 伪指令分配的内存需要字对齐.伪指令格式;{label} DCDO expr{,expr}{,expr}&其中 label 内存块起始地址标号.expr 地址偏移表达式或程序中的标号.内存分配的字数由 expr 个数决定.伪指令应用举例如下; IMPORT externsymDCDO分配 32 位的字单元,其值为标号 externsym 基于 R9 的偏移XDCFD和DCFDUDCFD 用于分配一段双字的内存单元,并用双精度的浮点数据 fpliteral 初始化。每 个双精度的浮点数占据两个字单元。DCFD 伪指令分配的内存需要字对齐。DCFDU 具有 DCFD 同样的功能,但分配的内存不需要字对齐。 伪指令格式:{label} DCFD fpliteral{,fpliteral}{,fpliteral}&{label} DCFDU fpliteral{,fpliteral}{,fpliteral}& 其中 label 内存块起始地址标号.fpliteral 双精度的浮点数. 伪指令应用举例如下;DCFD 2E30,-3E-20DCFDU -.1,1,2.1E18XDCFS和DCFSUDCFS 用于分配一段字的内存单元,并用单精度的浮点数据 fpliteral 初始化.每个 单精度的浮点数占据一个字单元.DCFD 伪指令分配的内存需要字对齐.DCFSU 具有 DCFS 同样的功能,但分配的内存不需要字对齐. 伪指令格式:{label} DCFS fpliteral{,fpliteral}{,fpliteral}&{label} DCFSU fpliteral{,fpliteral}{,fpliteral}& 其中 label 内存块起始地址标号fpliteral 单精度的浮点数.伪指令应用举例如下;DCFS 1.1E2,-1.3E10,0.0XDCI在 ARM 代码中,DCI 用于分配一段字节的内存单元,用指定的数据 expr 初始化.指定 内存单元存放的是代码,而不是数据.在 Thumb 代码中,DCI 用于分配一段半字节的内存单元,用指定的数据 expr 初始化. 指定内存单元存放的是代码,而不是数据.伪指令格式:{label} DCI expr其中 label 内存块起始地址标号. expr 可为数字表达式.DCI 伪指令和 DCD 伪指令非常类似,不同之处在于 DCI 分配的内存中的数据被标识 为指令.可用于通过宏指令业定}

我要回帖

更多关于 指令寻址方式 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信