>> 欢迎您,客人登录 按这里注册 忘记密码 在线 搜索 论坛风格  帮助  插件   


>>> 讨论Wolf Linux ,Arm Linux等
南开大学嵌入式系统与信息安全实验室学术论坛嵌入式Linux → 发表回复

主题标题: ARM指令系统
您目前的身份是: 客人 ,要使用其他用户身份,请输入用户名和密码。未注册客人请输入网名,密码留空。
请输入您的用户名   您没有注册?
请输入您的密码   忘记密码?
当前心情
  • 将放在帖子的前面
  •             
                
                
    上传附件或图片 (最大容量 99999KB)
    目前附件:(如不需要某个附件,只需删除内容中的相应 [UploadFile ...] 标签即可) [删除]
    内容 

    在此论坛中:

  • HTML  标签: 不可用
  • EMOTE 标签: 不可用
  • LeoBBS 标签: 可用
  • 贴图标签  : 允许
  • Flash 标签 : 允许
  • 音乐标签  : 允许
  • 文字大小  : 允许
  • 积分标签  : 允许
  • 保密标签  : 允许
  • 允许使用表情字符转换
  •   字体:  字号:  颜色:  插入 Real 音/视频 插入 WM 类音/视频  点这里查看 LeoBBS 论坛所有的专用标签
      粗体字 斜体字 下划线 居中 插入超级链接 插入邮件地址 插入图片 插入 Flash 动画 插入声音 插入代码 插入引用 插入列表 飞行字 移动字 发光字 阴影字 插入表情代码
     『 HTML 编辑器 』『 ASCII 字形生成器 』『 文本内容替换
     
      模式:帮助 完全 基本  >> 复制到剪贴板 | 查看长度 | 转换剪贴板超文本 <<
    点击表情图即可在帖子中加入相应的表情
     
    选项

    使用 LeoBBS 标签?
    是否显示您的签名?
    您是否希望使用表情字符转换在您的文章中?
    使用字体转换?
    加密此帖,只对部分用户可见,用户威望至少需要
    出售此帖,只有付钱才可以查看,售价 安元

        

    帖子一览:ARM指令系统 (新回复在最前,最多列出 6 个)  [列出所有回复]
    tanlintju 发表于: 2005/12/22 11:01am

    下面引用由kennyliu2004/11/18 04:07pm 发表的内容:
    本章将首先详细介绍ARM指令集,ARM指令集包括标准ARM指令集和Thumb指令集,并介绍ARM的宏汇编以及ARM汇编语言编程。
    3.1  ARM指令系统特点
    ARM指令系统属于RISC指令系统。标准的ARM指令每条都是32位长,有些ARM ...


     
    Bill95 发表于: 2005/09/22 03:53pm
    谢谢!
     
    wangning 发表于: 2005/04/24 12:21pm
    由于指令统一为32位,无法在1条指令中存放32位立即数。一般立即数为5~12位。采用一些特殊的方法,使它能处理立即数。
    同理,直接(或相对)地址一般为24位,但由于指令地址的低2位为00,故寻地范围为±226,相对地址为±225。
    这句话不大明白,能解释详细点吗?谢了
     
    kennyliu 发表于: 2004/11/18 04:07pm
    本章将首先详细介绍ARM指令集,ARM指令集包括标准ARM指令集和Thumb指令集,并介绍ARM的宏汇编以及ARM汇编语言编程。

    3.1  ARM指令系统特点
    ARM指令系统属于RISC指令系统。标准的ARM指令每条都是32位长,有些ARM核还可以执行Thmub指令集,该指令集是ARM指令集的子集,每条指令只有16位。
    1  数据类型
    ARM处理器一般支持下列6种数据类型:
    l8位有符号字节类型数据;
    l8位无符号字节类型数据;
    l16位有符号半字类型数据;
    l16位无符号半字类型数据;
    l32位有符号字类型数据;
    l32位无符号字类型数据;
    有些ARM处理器不支持半字和有符号字节数据类型。在ARM内部,所有指令都是32操作数据。短的数据数据类型只有在数据传送类指令中才被支持当1个字节数据取出后,被扩展到32位,在内部数据处理时,作为32位的什进行处理,并且ARM指令以字为边界。所有Thumb指令都是16位指令时,并且以2个字节为边界。
    ARM协处理器可以支持另外的数据类型,包括一套浮点数据类型,ARM的核并没有明确的支持。
    2  存储器组织
    图3-1所示为存储器组织。
    ARM这的地址的低三下四位必须为00,半字地址的最低位为0。字的内容在存储器中的存放通常有两种方式,即小端(little-endian)和大端(big-endian),这两种方式的不同在于最低位字节的地址是否在最高位字节的地址之前。小端方式每个字的低位字节在后,例如0x12345678小端方式存放如下:
    地址                      内容
    A                          78
    A+1                        56
    A+2                        34
    A+3                        12
    大端方式的存放如下:
    地址                      内容
    A                          12
    A+1                        34
    A+2                        56
    A+3                        78
    大多数的ARM处理器芯片都不得可以支持上面两种方式,一般缺省为小端。





    23222120

    19181716
    word16
    15141312
    half-world12  half-word14
    111098
    word8
    7654
    byte6 half-word4
    3210
    byte3 byte2 byte1 byte0
    20212223

    16171819
    word16
    12131415
    half-world12  half-word14
    891011
    word8
    4567
    Byte5 half-word6
    0123
    Byte0 byte1 byte2 byte3

    (a)小端存储器组织                                    (b)大端存储器组织
    图3-1  存储器组织

    3  ARM指令特点
    1.每条指令的多功能
    ARM指令一个重要的特点是它所有的指令都带有条件,例如用户可以测试某个寄存器的什但是直到下次使用同一条件进行测试时,才能有条件的执行这些指令。ARM指令另一个重要的特点是具有灵活的第2操作数,既可以是立即数,也可以是逻辑运算数,使得ARM指令可以在读取数值的同时进行算术和移位操作。它可以在几种模式下操作,包括通过使用SWI(软件中断)指令从用户模式进入系统模式。
    2.  协处理器的作用
    ARM内核可以提供协处理器指令接口,通过扩展协处理器完成复杂的功能,因此,ARM指令还包含了多条协处理器接口,使用多达16个协处理器;允许将其他处理器能过协处理器接口进行耦合;还包括几种内丰管理单元的变种;包括简单的内存保护到复杂的内存保护到复杂的页面层次。例如,管理存储部件MMU就是ARM内核通过协处理器CP15实现对内存的管理。
    3.  Thumb指令
    ARM有两种指令集:16位Thumb指令集和32位ARN指令集。使用16位的存储器可以降低成本,在这种情况下,Thumb指令集的整体执行速度比32位指令集快,而且提高了代码密度,所以一般用Thumb编译器将C语言程序编译成16位的代码。处理器一开始总在arm状态,可使用BX指令转换到Thumb状态。
    4.  具有RISC指令的特点
    由于ARM指令属于RISC指令,所以具有RISC指令的特点,指令少,且等长,便于充分利用流水线技术;使用多寄存器,且多为简单的Load与Store指令(从内存中读取某个值,执行完操作后再将其放回内存)。
    5.  立即数和直接地址
    由于指令统一为32位,无法在1条指令中存放32位立即数。一般立即数为5~12位。采用一些特殊的方法,使它能处理立即数。
    同理,直接(或相对)地址一般为24位,但由于指令地址的低2位为00,故寻地范围为±226,相对地址为±225。
    3.2  ARM指令系统

    3.2.1  ARM指令的寻址方式
    每条ARM指令都是32位指令,在大多数情况下,可以有3个操作数,其中第1个操作数或目的操作数一般为基本操作数方式。ARM指令的基本寻址方式有:
    l寄存器寻址
    例:
    ADD R0,R1,R2                                ;(R1)+(R2)→R0
    l立即数寻址
    例:
    ADD R3,R3,#2                                ;(R3)+2→R3
    l寄存器间接寻址
    例:
    LDR R0,R0,[R3]                              ;((R3))→R0
    l寄存器变址
    例:
    LDR R0,[R1,#4]                              ;((R1)+4)→R0
    l相对寻址
    例:
    B rel                                         ;(PC)+rel→PC
    另外,每条ARM指令中还可以有第2条和第3条操作数,它们采用复合寻址方式,ARM的复合寻址方式有5种。
    1  第2操作数的寻址方式
    ARM运算指令和某些数据传送指令除了目的操作数和第1个操作数(它们为寄存器寻址)外,还具有第2操作数。该第2操作数具有以下寻址方式:
    (1)立即寻址(#immediate_8*r*2)
    由8位立即数和4位移位位r决定。R指定左移rⅹ2位,r=0~15,实际上可移位0,2,4,6,···,28,30。例如:实际的立即数可以为0xFF(r=0),0xFF0(r=2),0xFF000000(r=12), 0xFF000000F(r=14)等。
    例:
    MOV R0,#20
    (2)寄存器直接(Rm)
    例:
    MOV R0,R1
    (3)寄存器移位(Rm,移位码#immed_5)
    移位码包括:LSL、LSR、ASR、ROR、RPX的任何一种,移位位数由#immed_5决定。详细请见ARM数据处理类指令的第2操作数。
    例:
    MOV R0,R1,LSL #1                       ;(R1)*2→R0
    (4)寄存器间接移位(Rm,移位码Rs)
    移位码包括:LSL、LSR、ASR、ROR,移位位数由Rs的内容决定。
    例:
    MOV R0,R1,R2,LSL,R2                         ;(R1)*(R2)→R0

    2  字和无符号字节寻址方式
    ARM中的取数指令的源操作数和存数指令的目的操作数采用带偏移量的变址方式,可以表示为基址+变址寻址。有效地址寄存器的内容加上偏移量的值。对于字和无符号字节,寻址方式通常可以包括3种:寄存器间接寻址,前变址偏移寻址和后变址偏移寻址。带偏移量的变址包括常数蔌寄存器值。
    (1)存器间接寻址)[Rn])
    例:
    LDR R0,[R1]                              ;((R1))→R0
    STR R0,[R1]                              ;(R0)→(R1)
    (2)前变址偏移寻址([Rn,偏移量]{!})
    在数据传送之前,瘵偏移量加到Rn中。其结果作为传送数据的存储器地址。若使用后缀“!”,则结果写回到Rn中,Rn不允许是R15。
    该寻址方式又分为下列3种:
    ①立即数偏移寻址[Rn,#±<immed_12>]{!}
    例:
    LDR R0,[R1,#5]!                   ;((R1+5)→R0,(R1)+5→R1
    ②寄存器偏移[Rn,#±Rm{!}

    LDR R0,[R!R1,-R2]                 ;((R1)-(R2))→R0
    ③移位寄存器偏移
    [Rn, ±Rm,LSL #<immede_5>{!}
    [Rn, ±Rm,LSL #<immede_5>{!}
    [Rn, ±Rm,ASR #<immede_5>{!}
    [Rn, ±Rm,ROR #<immede_5>{!}
    [Rn, ±Rm,RPX]{!}
    例:
    LDR R0,[R1,R2,LSL #2]                          ;((R1)+(R2)*4→R0
    (3)后变址偏听偏信移寻址([Rn],偏移量)
    Rn的值用作传送数据的存储器地址。在数据传送后,偏移量加到Rn中,结果写回到Rn。Rn不允许是R15。
    该寻址方式又分为下列3种:
    ①立即数偏移[Rn],#±<immde_12>
    例:
    LDR R0,[R1],#4                           ;((R1))→R0,(R1)+4→R1
    ②寄存器偏移[Rn],±Rm
    例:
    LDR R0,[R3],-R8                        ;((R3))→R0,(R3)-(R8)→R3
    ③移位寄存器偏移
    [Rn],±Rm,LSL#<immde_5>
    [Rn],±Rm,LSR#<immde_5>
    [Rn],±Rm,ASR#<immde_5>
    [Rn],±Rm,ROR#<immde_5>
    [Rn],±Rm,RPX
    例:
    LDR R0,[R3],R8,LSL#2                 ;((R3))→R0,(R3)+(R8)*4→R3
    3  半字和有符号字节寻址方式
    ARM中的半字和有符号字节取数和存数指令的寻址方式与字和无符号字节的寻址方式略有不同。
    (1)寄存器间接寻址([Rn])
    例:
    LDR R0,[R1]
    STR R0,[R1]
    (2)前变址偏移寻址([Rn,偏听偏信移量]{!})
    (3)在数据传送之前,将偏移量加到Rn不允许是R15。
    该寻址方式又分为下列两种:
    ①立即数偏移[Rn,#±<immed_8>]{!}
    例:
    LDR R0,[R5,#22]!              ;((R5+22)→R0,(R5)+22→R5
    ②寄存器偏移[Rn,±Rm]{!}
    例:
    STRB R0,[R3,-R8]               ;(R0)→(R3)-(R8),(R3)-(R8)→R3
    (4)后变址偏听偏信移寻址(Rn),偏移量)
    Rn的值用作传送数据的存储器地址。在数据传送后,偏移量加到Rn中,结果写回到R n。Rn不允许是R15。
    该寻址方式又分为下列3种:
    ①立即数偏移[Rn],#±immed_8>
    例:
    LDR R0,[R3],-R8                           ;((R5))→R0,(R5)+22→R5
    ②寄存器偏移[Rn],±Rm
    例:
    STR R0,[R3],-R8                           ;(R0)→(R3),(R3)-(R8)→R3
    4  块寻址
    ARM对堆栈的使用一般用多寄存器传送指令,是一种有效的保存处理器状态格多字节传送的有效方式。ARM硬件中的堆栈分为以下4种:]
    ①满向上生长型:堆栈按高地址方向生长,当前堆栈指针指向一个有效值;
    ②空向上生长型:堆栈按高地址方向生长,当前堆栈指针指向一个空值;
    ③满向下生长型:堆栈按低地址方向生长,当前堆栈指针指向一个有效值;
    ④空向下生长型:堆栈按低地址方向生长,当前指针指向一个空值。
    图3-2说明了4条带不同变量和多字节传送前后和内存变化,以及基寄存器的变化情况。指令执行前的基寄存器是R9,指令执行后的基寄存器是R9’。
    常见多字节传送指令如表3-1所示。
    表3-1内FD|ED|FA|EA后缀只在堆栈时使用。F和E、分别代表指针指向为满或空。A和D分别表示堆栈是否向上或向下生长。例如:堆栈如果是向上生长,STM指令向上存放,LDM指令向下读取。IA、IB、DA、DB后缀在一般数据传送时使用。注意:LDMED与LDMIB是同一条指令(下同)。


    图3-2多寄存器传送示意

    表3-1常见多字节传送指令


    5  协处理器寻址方式
    ARM协处理器寻址方式包括以下4种方式:
    (1)寄存器直接寻址([Rn]);
    (2)前普址偏移寻址([Rn,#±<immed_8*4>]{!});
    (3)后变址偏移寻址([Rn],#±<immed_8*4>);
    (4)带参数无偏移寻址([Rn],{8-bit copro.Option}。

    3.2.2 ARM指令的条件执行
    每条ARM指令都是有条件执行,包括特权调用和协处理器指令,可根据执行结果来选择是否更新条件码。若要更新条件码,则指令中须包含后缀“S”。条件占32位指令的高4位。
    一些指令(如CMP、CMN、TST、和TEQ不需要后缀“S”。它们唯一的功能就是更新条件标志,且始终更新条件码。更新之前保持不变。没执行的条件指令对标志没影响,一些指令只更新部分标志,不影响其他标志。
    可以根据另外指令设置的标志,有条件地执行某条指令,分如下两种情况:
    l在更新标志的指令后立即执行;
    l在插入的几条不更新标志的指令后执行。
    条件码中的N、Z、C和V位的值将决定指令如何执行。条件如表3-2所示。
    表3-2  ARM条件码


    表3-2中符号“*”的说明:HS、LO、HI、LS这4个条件码指的是无符号数,GE、LT、GT、LE这4个条件码指的是符号数。

    3.2.3 Load/Store类指令
    1.  单字和无符号字节Load/Store类指令
    功能:提供ARM寄存器和内存之间单字节(8位)数据的传送。

    格式:
    (1)零偏移(zero offet)
    LDR|STR{<条件码}}{B}{T} Rd,[Rn]   ;((Rn))→Rd
    零偏移指的是将Rn的内容作为传送数据的地址。
    (2)前变址(pre-indexed offet)
    LDR|STR{<条件码>}{B} Rd,[Rn,<offset>]{!}
    ;((Rn)+offset)→Rd
    ;有“!”,(Rn)+offset→Rn
    ;无“!”,Rn不变
    前变址指的是在数据传送之前,将偏移量加到Rn中,其结果作为传送数据的存储地址。若使用后缀“!”,则结果写回到Rn中。Rn不允许是Rn15。
    (3)  程序相对偏移(program-relative)
    LDR|STR{<条件码>}Rd,Ladel      ;(Label) →Rd
    程序相对偏移指的是由PC计算偏移量,并将PC生成指令。不能使用后缀“!”。“LDR Rd,Label”等价为“LDR  Rd,[Rn],offset”等价为“((Rn))→Rd,(Rn)+offset→Rn]”
    (4)  后变址(post-indexed offset)
    LDR|STR{<条件码>{B}{T} Rd,[Rn],<offset>
    后变址指的是将Rn的值用作传送数据的存储器地址,数据传送后,偏移量加到Rn中,结果写回到Rn。Rn不允许是R15。“LDR Rd,[Rn],offset”等价为“((Rn))→,(Rn)+offset→Rn”。
    其中:
    B      可选后缀。若有B,则传送Rd的最低有效字节。若操作码是LDR,则将Rd的其他字节清零。
    T      可选后缀。若有T,那么即使处理器在特权模式下,存储系统也将访问看成是处理器在用户模式下。T在用户模式下无效,不能与前变址偏移一起使用T。
    Rd     ARM寄存器。
    Rn     存储器的基址寄存器,若指令是带写回(write back)的前变址(后缀为“!”)或后变址,或使用T后缀,则不允许Rn与Rd相同。
    Offset  Rn上的偏移量。
    Label   程序相对偏移表达式,必须在当前指令的前指令的±4KB内。
    !      可选后缀。若有“!”则将包含偏移量的地址写回到Rn。若Rn是R15,则不能使用后缀“!”。

    注释:
    (1)  offset 说明
    前变址和后变址格式中的offset可以是2种形式之一:
    (2)  exression
    其含义是符号表达式,通常是数字整数常量,取值在-4095~+4095之间。
    (3)  ±Rm{.shift}
    其中:
    ±         可选负号。若有符号“-”,则从Rn中减去偏移量。否则,将偏移量加到Rn中。
    Rm         内含偏移量的寄存器。Rm不允许是R15。
    Shift      Rm的可选移位方法。可以是ASR、LSL、LSR、ROR、RRX的任何一种。详细说明见ARM数据处理类指令的第二操作数。
    (4)  字地址对准
    大多数情况下,必须保证用于32位传送的地址是32位对准的。
    若系统中有协处理器(CP15),则允许对准检查,若允许对准检查,则非字对准的32位传送会引起对准异常。若系统中没有系统协处理品(CP15),或禁止对准检查,则有:
    对于STR,将指定的地址取成4的倍数。
    对于LDR,则
    l将指定的地址取成4的倍数。
    l由结果地址读取4个字节的数据。
    l依据地址的位[1:0],将读取的数据循环右移1、2或3个字节。
    对于小端存储系统,这使寻址的字节占用寄存器的最低有效字节。
    对于大端存储系统,这使寻址的字节占用:
    -位[31:24],若地址的位[0]为0;
    -位[15:8],若地址的位[0]为1。
    (5)  使用R15读取
    使用R15(程序计数器)读取会引起处理器转移到所读取地址的指令。
    对于读取值的位[1:0],有:
    l对于ARM体系结构v3及以下版本,忽略位[1:0]。
    l对于ARM体系结构v4及以上版本的非T变量,位[1:0]为0。
    l对于ARM体系结构v5及以上版本的T变量,则有
    -对于读取到R15的值,其位[1:0]不允许是ob10;
    -对于读取到R15的值的位[0]置位,则处理器转到Thumb状态。
    当使用R15读取时,不能使用后缀“B”或“T”。
    (5)  使用R15存储
    通常应尽量避免使用R15存储。
    若使用R15存储,则存储的值是当前指令的地址加上实现所定义的常量。对于特写的处理器这个常量始终不变。
    例 1:将R0中的内容存放进外设中。
            LDR    R1,UARTADD      ;将UART地址放进R1中
            STRB   R0,[R1]         ;将数据放进外设中
    UARTADD  &      &1000000         ;UARTR的地址值
    例 2:
    LDR    R8,[R10]!               ;((R10))→R8
    LDRNE  R2,[R5,#960]!             ;Z≠14时((R5)+960)→R2,(R5)+960→R5
    STR    R2,[R9,#consta-struc]   ;consta-struc是常量的表达式,该常量的范围为1~4095
    STRB   R0,[R3,-R8,ASR#2]      ;R0→(R3-R8/4),存储R0的最低有效字节,R3和R8不变
    STR    R%,[R7],#-8              ;读取一个字,该字位于标号loacaldata所在地址

    2.  半字和有符号字节Load/store类指令
    功能:提供ARM寄存器和内存之间半字(16位)和有符号字节(8位)数据的传送。

    格式:
    (1)  零偏移(zero offset)
    LDR|STR{<条件码>}H|SH|SB  Rd,[Rn]
    (2)  前变址(pre-indexed offset)
    LDR|STR{<条件码>}H|SH|SB  Rd,[Rn,<offset>]{!}
    (3)  程序相对偏移(pregram-relatve)
    LDR|STR{<条件码>}H|SH|SB  Rd,Label
    (4)  后变址(post-indexed offset)
    LDR|STR{<条件码>}H|SH|SB  Rd,[Rn],<offset>
    其中:
    H|SH|SB 表示数据类型选择。
           SH 对有符号半字(仅LDR);
           H  对无符号半字;
           SB 对有符号字节(仅LDR)。
    Label   程序相对偏移表达式。必须是在当前指令的±255字节范围内。
    Offset  加在Rn上的偏移量。含义见注释。
    Rn和“!”同前面第1条(LDR和STR字和无符号字节)。

    注释:
    (1)  offset说明
    前变址和后变址格式中的offset可以是下两种形式之一:
    ①expression含义同前一条指令,取值在-255~+255范围之间。
    ②±Rm含义同前一条指令。
    (2)  半字传送的地址对准
    半字传送的地址必须是偶数。
    若系统有系统协处理器(CP15),则可允许对准检查。若允许对准检查,则非对准的16位传送会引起对准异常。若系统没有系统协处理器(CP15)或禁止对准检查,则有
    l非半字对准的16位读取将使Rd内容不可靠;
    l非半字对准的16位存储将使在address和(address-1)的2个字节不可靠。
    (3)  不能将半字或字节读取到R15。
    例 1:
    LDREQSH  R11,[R6]      ;(有条件地)R11←[R6],读取16位半字,有符号扩展到32位
    LDH      R1,[R0,#22]   ;R1←[R0+22],读取16位半字,零扩展到32位
    STR      R4,[R0+R1]    ;存储最低的有效半字到R0+R1地址开始的两个字节,地址写回到
    ;R0
    LDRSB    R6,constf     ;读取位于标号constf地址中的字节,有符号扩展
    例 2:
    ADD     R1,ARRAY1          ;ARRAY1 为半字数组
    ADR     R2,ARRAY2          ;ARRAY2为字数组
    ADR     R3 ENDARR1         ;ARRAY1+2
    LOOP LDRSH   R0,[R1],#2         ;取得有符号半字数,扩展为字
    STRR0,[R2],#4
    CMP     R1,R3
    BLT     LOOP

    3.  双字Load/Store类指令
    功能:提供ARM寄存器和内存之间双字(64位)数据的传送.

    格式:
    (1)  零偏移(zero offset)
    LDR|STR{<条件码>}D Rd,[Rn]
    (2)  前变址格式(pre-indexed offset)
    LDR|STR{条件码>}D Rd,[Rn,<offset>]{!}
    (3)  程序相对偏移(pregram-relatve)
    LDR|STR{<条件码>}D Rd,LABEL
    (4)  后变地址格式(post-indexed offset)
    LDR|STR{<条件码式>}D Rd,[Rn],<offset>
    其中:
    Rd  读取或指令寄存器其中的一个,另一个是R(d+1).Rd必须是偶数寄存器,且不是R14.
    Rn  除非指令为零移,或不带写回的前索引,否则R不允许是Rd和R(d+1)相同.
    Offset 加在Rn上的偏移量.含义同3.2.3节第1条指令.
    Label 程序相对偏移表达式.Label必须是在当前指令的±255字节范围内.
    !     可选后缀.若有”!”,则包含偏移量的最后地址写回到Rn.

    注释:
    对于双字节传送,地址必须是8的倍数.若系统有系统协处理器,可允许对准检查.若允许对准检查,慢非双字准的64位传送将引起对准异常.该指令适用于ARMv5TE指令系统及以上版本.
    例:
    LDARD R6,[R11]                   ;((R11)→R6,((R11)+4)→R7
    STRD  R4,[R9,#24]                ;(R4)→(R9)+24,(R5)→(R9)+24

    4.  多寄存器Load/Store类指令
    功能:读取和存储多个寄存器,可以传送R0~R15的任何组合.

    格式:
    (1)  标准格式
    LDR|STM{<条件码>}<mode>Rn{!}<寄存器>
    (2)  非用户模式下,用下面可以同时把当前的SPSR写入CPSR中,转向用户模式,寄存器组饮包含PC.
    LDM{<条件码>}<mode>Rn{!},<寄存器组+PC>^
    (3)  非用户模式下,用下面格式可以实现访问用户模式的寄存器,但寄存器组不包含PC.
    LDM|STM{<条件码>}<mode>Rn,<寄存器组-PC>^
    其中:
    mode IA、IB、DA、DB、FD、ED、FA、EA之一。
    Rn   基址寄存器,装有传送数据的初始地址。Rn是不允许是R15。
    !   可选后缀。若有“!”,则结果地址写回到Rn。
    Reglist读取或存储的寄存器列表,包含在括号中,它也可包含寄存器的范围。若包含多于1个寄存器列表或包含寄存器范围,则必须用逗号分开。
    ^    可选后缀,不允许用户模式或系统模式下使用。它有两个目的:
    l操作码是LDM且reglist中饱包含PC(R15),那么出除了正常的多寄存器传送外,将SPSR也拷贝到CPSR中.这用于从异常处理返回,仅在异常模式下使用。
    l数据传入或传出的是用户模式的寄存器,而不是当前模式的寄存器。
    注意:对于LDM指令,如包含PC,位0=1时,转至Thumb状态.寄存器组中一般不应有Rn,它至少有1个寄存器。FD、ED、FA、DA用于堆栈操作;IA、IB、DA、DB用于一般的数据传送。

    注释:
    (1)非字对准地址
    这些指令忽略地址的位[1:0]。在带有系统协处理器的系统中,若对准检查使能,则这2位的非零值将引起对准异常。
    (2)读取到R15
    到R15(程序计数器)的读取将引起处理器转移到读取地址处的指令。在ARM体系结构v5及以上版本的T变量中若读取的位[0]置位,则到R15的读取将导致处理器切换到执行Thumb指令。
    (3)带写回的存/取基址寄存器
    如果Rn包含在寄存器列表中,且用后缀“!”,指明要写回(write back),那么:
    l若操作码是STM,县城Rn是寄存器列表中数字最小的寄存器,则将初值保存。
    lRn的读取和储存值不可预知。
    例1:若保存3个工作寄存器状态和返回地址:
    STMFD R13!,{R0-R2,R14}
    若恢复3个工作寄存器状态和返回地址:
    LDMFD R13!,{R0-R2,R14}
    例2:
    LDMFD R8,{R0,R2,R9}                 ;((R8))→R0
                  ;((R8)+4)→R2
                  ;((R8)+8)→R9
    STMDB R1!,{R3-R6,R11,R12}           ;(R3)→R1-4
               ;(R4)→R1-8
                ;(R5)→R1-12
                ;(R6)→R1-16
                 ;(R11)→R1-20
    ;(R12)-24→R1
    STMD  R13!,{R0,R4-R7,LR}            ;寄存器进栈
    例3:子程序调用
    SUMB1 STMFD  SP!,{R0-R2,R14}         ;保护R0~R2和返回地址
    ……         ;其它指令
    BL                               ;允许子程序嵌套
    ……                             ;其它指令
    LDMFD SP!,{R0-R2,R15}          ;恢复R0~R2,返回子程序调用程序后执行

    5.  预读取PLD指令
    功能:cache预读取(PLD,PreLoad),使用PLD指示存储系统从后面几条指令所指定的存储器地址读取,存储系统可使用这种方法加速以后的存储器访问。

    格式:
    PLD[Rn,{offset}]
    其中:
    Rn         存储器的基址寄存器。
    Offset     加在Rn上的偏移量。含义同3。2。3节第1条指令。

    注释:
    PLD指令适用于ARM v5TE指令及以上版本。
    例:
    PLD   [R9,#-2481]
    PLD   [R0,#av*4]            ;av*4必须在汇编时求值,范围为-4095~4095内的整数
    PLD   [R5,r8,Lsl#2]

    6.  内存和寄存器交换类指令
    功能:用一条指令实现在寄存器和存储器之间交换数据。

    格式:
    SWP{<条件码>}{B} Rd,Rm,[Rn]              ;((Rn))→Rd,Rm→Rn
    ;n≠m,d
    其中:
    B   可选后缀。若有B,则交换字节;否则,交换32位字。
    Rd  ARM寄存器。数据从存储器读取到Rd。
    Rm  ARM寄存器。Rm的数据存储到存储器。Rm可以与Rd相同。Rn必须与Rd和Rm不同。

    注释:
    对非字对准地址的处理同LDR和STR指令。
    例:
    ADR   R0,SEMAPHORE
    SWPB  R1,R1,[R0]            ;交换字节

    3.2.4  ARM数据处理类指令
    大多数ARM通用数据处理有一个灵活的第2操作数(flexi second operand)。在每一个指令的格式中以“operand2”表示。
    第2条操作数有如下2种可能的格式:
    (1)#immed_8r
    常量的表达式。常量必须对应于8位位图(pattern0。该位图在32位字中,被循环移位偶数位(0,2,4,8,…,26,28,30)。合法常量:0xFF、0xFF000、0xF0000000F。非法常量:0x101、0xFF04、0xFF003、0xFFFFFFFF。
    (2)±Rm {,shift}
    Rm     存储第2操作数ARM寄存器。可用各种方法对寄存器中的位图进行移位或循环移位。在指令操作的结果用作第2操作数,但Rm本身不变。
    Shift  Rm的移位方法,可以是下面的任何一种:
    ASR n        算术右移n位(1≤n≤32)。
    LSL n        逻辑左移n位(0≤n≤31)。
    LSR n        逻辑右移n位(1≤n≤32)。
    ROR n        循环右移n位(0≤n≤32)。
    RRX          带进位的循环右移1位。
    Type Rs 其中:Type ASR、LSR、ROP中的种;
                 Rs   提供移位量的ARM寄存器,仅使用于最低有效字节。
    ASR、LSL、LSR、ROP和RRX的详细说明如下:
    ①  ASR
    若将Rm中的内容看作是有符号的补码整数,那么算术右移(ASR,Arithmetic Shift Right)n位,即Rm中的内容除以 。将原来的位拷贝到寄存器左边的n位中(即空出的最高补符号位),见图3-3(a)。
    ②  LSR和LSL
    若将Rm中内容看作是无符号整数,则逻辑右移(LSR,Logical Shift Right)n位,即Rm中的内容除以 ,寄存器左边的n位置0,见图3-3(b)。
    若将Rm中内容看作是无符号整数,则将逻辑左移(LSR,Logical Shift Left)n位,即Rm四的内容乘以 ,可能会出现溢出且无警告,寄存器右边的n 位置0,见图3-3(b)。
    ③  ROR
    循环右移(ROR,Rotate Right)n位,把寄存器内容循环右移,见图3-3(c)。
    ④  RRX
    若将Rm中内容看作是无符号整数,则带进位右环移n位,寄存器左边的n位置0,见图3-3(d)。


    图3-3移位操作过程
    1  数据运算类指令
    功能:完成数据在寄存器中的运算,这些运算包括32位数据的算术、位操作,其中某一个操作数可以经过移位或循环运算。

    格式:
    <操作码>{<条件码>}{S}Rd,Rn,Operand2
    操作码 包括ADD、SUB、RSB、ADC、SBC、RSC、AND、ORR、EOR、BIC、MOV、MVN、CMP、CMN、TST和TEQ指令。
    其中:
    S       可选后缀。若指定S,则根据操作结果更新条件标志(N、Z、C和V)。
    Rd      ARM结果寄存器。
    Rn      存储第1操作数的ARM寄存器。
    Operand 第2操作数。详细说明请见3.2.4节第2操作数说明。
    ARM的数据运算类指令用法如表3-3所示。
    表3-3 ARM运算类指令


    注释:
    (1)  条件码标志
    若指定S,那么ADD、SUB、RSB、ADC、SBC、RSC指令根据结果更新标志N、Z、C和V。CMP、CMN、TST和TEQ指令不需S。注意:减法(含比较)够减时,C=1。而AND、OPR、EOP、BIC、MOV和MVN指令将:①根据结果更新标志N和Z;②计算Operand2时更新标志C;③不影响V标志。
    (2)  R15的使用
    ADD、SUB、RSB、ADC、SBC、RSC、AND、ORR、EOR、BIC、MOV和MVN指令将R15作为Rn使用,那么使用的值是指令的地址加8。
    若将用R15作为Rd,则
    l执行转移到结果对应的地址。
    l若后缀“S”,则将当前模式的SPSR拷贝到CPSR。可以使用这点从异常返回。
    在有寄存器控制移位的任何数据处理指令中,不能将R15作为Rd或任何操作数来使用。
    CMP、CMN、TST和TEQ指令若将R15用作Rn,则使用的值是指令的地址加8。在有寄存器控制移位的任何数据处理指令中,不能将R15用于任何操作数。
    例1:
    ADD     R2,R1,R3        ;(R1)+(R3)→R2
    例2:
    SUBS    R2,R2,#1        ;(R2)-1→R2
    BEQ   LABEL                    ;如等于0,转向LABEL
    例3:R0中的内容乘以5:
    ADD     R0,R0,R0,LSL #2     ;(R0)*5→R0
    ADD     R0,R0,LSL #1
    例4:R0中的内容乘以10:
    ADD     R0,R0,R0,LSL #2     ;(R0)*10→R0
    MOV     R0,R0,LSL #1
    例5:R0中的内容乘以10,再加R1中的内容:
    ADD     R0,R0,R0,LSL #2     ;(R0)*10+R1→R0
    MOV     R0,R1,R0,LSL #1
    例6:
    ADDS R2,R2,R0                ;(R3R2)+(R1R0)→R3R2
    ADC  R3,R3,R1
    例7:
    ADDNE R0,R1,#&ff              ;if Z=0 then(R1)+0xff→R0
    例8:R1中的内容乘7,送给R0:
    RSB   R0,R1,R1,LSL #3       ;(R1)*7→R0

    2  前导零计数指令
    功能:CLZ(Count Leading Zeros)指令对Rm中值的高位(leading zeros)个数进行计数,结果放到Rd中。若源寄存器全为0,则结果为32。若[31]为1,则结果为0。

    格式:
    CLZ{<条件码>}Rd,Rm
    其中:
    Rd ARM结果寄存器,Rd不允许是R15。
    Rm 操作数寄存器。
    注释:
    CLZ指令适用于ARM v5指令系统以上版本。这条指令不影响条件码标志。
    例:
    CLZ    R4,R9
    CLZNE  R2,R3

    3  乘法指令
    格式:
    (1)  MUL{<条件码>}{S},Rd,Rm,Rs
    (2)  MLA{<条件码>}Rd,Rm,Rs,Rn
    其中:
    Rd          结果寄存器。
    Rm,Rs,Rn    操作数寄存器。
    R15不能用于Rd,Rm,Rs或Rn。Rd不能与Rm相同。
    (3)  <mul>{<条件码>}{S}RdHi,RdLO,Rm,Rs
    mul中类型包括UMILL、UMLAL、SMULL、SMLAL。
    其中:
    RdLo,RdHi  ARM结果寄存器。对于UMLAL和SMLAL,这两个寄存器用于保存累加值。
    Rm,Rs     操作数寄存器。
    R15不能于RdHi,RdLo,Rm或Rs。RdLO、RdHi和Rm必须是不同的寄存器。
    (4)  SUML<x><y>{条件码}Rd,Rm,Rs
    其中:
    <x>  B或T。B意味着使用Rm的低端(位[15:0]),T意味着使用Rs的高端(位[31:16])。
    <y>  B或T。B意味着使用Rm的低端(位[15:0]),T意味着使用Rs的高端(位[31:16])。
    Rd 结果寄存器。
    Rm,Rs 乘数寄存器。
    R15不能用于Rd,Rm和Rs。Rd、Rm、Rs可用相同的寄存器。
    (5)  SMLA<x><y>{条件码}Rd,Rm,Rs可用相同的寄存器。
    其中:
    <x>、<y>、Rm和Rn含义同SMUL<x><y>指令。
    R15不能用于Rd、Rm和Rs。Rd、Rm、Rs可用相同的寄存器。
    (6)  SMULW<y>{条件码}Rd,Rm,Rs
    其中:
    <y>、Rd、Rm、Rs和Rn含义同SMUL<x><y>指令。
    R15不能用于Rd、Rm和Rs。Rd、Rm、Rs可用相同的寄存器。
    (7)  SMULW<y>{条件码}Rd,Rm,Rs
    其中:
    <y>、Rd、Rm、Rs和Rn含义同SMUL<x><y>指令。
    R15不能用作Rd、Rm、Rs或Rn的任何一个。任何Rd、Rm、Rs或Rn可用相同的寄存器。
    (8)  SMULW<y>{条件码}Rd,Rm,Rs,Rn
    其中:
    <y>、Rd、Rm、Rs和Rn含义同SMUL<x><y>指令。
    R15不能用作Rd、Rm、Rs或Rn的任何一个。任何Rd、Rm、Rs或Rn可用相同的寄存器。
    (9)  SMULW<y>{条件码}RdLo,RdHi,Rm,Rs
    其中:
    <x><y>含义同SMULxy指令。
    RdHi,RdLo    结果寄存器。它们也存储累加值。
    Rm,Rs        乘数寄存器。
    ARM乘法类指令用法如表3-4所示。
    表3-4 ARM乘法类指令


    注释:
    若指定S标志位,则MUL和MLA指令将:①根据结果更新标志N和Z;②不影响标志V;③在ARM v4以前版本中标志C不可靠;④在ARM v5及以后版本中不影响标志C。
    若指定结果S标志位,则UMULL,UMLAL,SMULL和SMLAL指令将:①根据结果更新标志N和Z;②在ARM v4及以前版本中标志C不可靠;③在ARM v5及以后版本中不影响标志C或V。
    SMULAxy指令不影响任何条件码标志。若加法出现溢出,则置位标志Q。使用MRS指令读标志Q的状态。注意:这条指令永远也不会清除Q标志。要清除Q标志,则应使用MSR指令。
    SMULxy、SMULWy、SMLALxy指令不影响任何条件标志。
    SMULxy、SMULWy、SMLALxy、SMLAxy和SMLAWy指令适用于ARM v5TE指令系统及以上版本。
    例:
    SMLALLES               R8,R9,R7,R6
    SMULLNE                R0,R1,R9,R0

    4  QADD、QSUB、QDAAA和QDSUB指令
    功能:这4条指令属于DSP增强指令,完成饱和加、饱和减,饱和乘2加、饱和乘2减4种饱和运算功能。

    格式:
    <操作码>{条件码}Rd,Rm,Rn
    <操作码>包括:QADD、QSUB、QDADD和QDSUB指令。
    其中:
    Rd      结果寄存器。
    Rm,Rn   操作寄存器。

    注释:
    饱和运算是DSP指令所特有的功能,对加/减法指令的结果做了如下修改:
    (1)  如果加/减法指令的结果在- ~ -1之间,饱和运算的结果取加/减法指令的结果。
    (2)  如果加/减法指令的结果大于 -1,饱和运算的结果取最终结果为 -1。
    (3)  如果加/减法指令结果小于- ,饱和运算的结果取最终结果为时尚- 。
    QDADD和QDSUB指令计算SAT(Rm+SAT(Rn*2)),饱和可发生在加倍操作,加法上,或两咱情况下同时发生。或饱和仅发生在加倍操作上,则标志Q置位,但最后结果是不饱和的。SAT意为饱和运算。
    这些指令不影响标志N、Z、C和V。若出现饱和,则置位Q标志。可使用MRS指令来读Q标志的状态。注意:即使是饱和不出现,这些指令也从不清除Q标志。使用MSR指令清除Q标志。
    QADD、QSUB、QDADD和QDSUB指令适用于ARM v5TE指令系统及以上版本。
    例:
    QADD       R0,R1,R9        ;SAT(R1+R9)→R0
    QDSUBLT    R9,R0,R1        ;SAT(R0-SAT((R9)*2))→R9

    3.2.5  ARM转移类指令
    ARM转移类指令完成循环、调用子程序和从ARM状态转向Thumb状态等功能,包括B、BL、BX和BLX指令。

    1  转移/转移带链接类指令
    功能:B、BL指令完成当前执行指令地址的转移,偏移地址量可以达到32M,BL指令可以把转移指令后第1条指令的地址放进链接寄存器R14中完成连接作用,通常用来完成子程序的调用。
    转移地址通常由24位有符号数组成,由于指令地址的代位为00,故可进行2位的左移运算,因此总的偏移量达到±32M。

    格式:
      B{L}{<条件码>}<Label>
    其中:
    Label    程序相对偏移表达式。

    注释:
    BL(Branch and Link)指令将下一条指令的地址拷贝到R14(LR,链接寄存器)并引起处理器转移到Label。BL指令(L=1),等价于先把(PC)→R14,再(PC)+offset→PC.
    机器级的B和BL指令限制在当前指令的± (±32M)字节范围内。但是,即使Label走超出了该范围,汇编可以使用这些指令。
    例1:条件转移。
    CMP   R0,35             ;如果R0小于5
    BLT   SUB1               ;则转SUB1
    BGE   SUB2               ;否则转SUB2
    例2:程序调用。
    BL    SUB                ;调用子程序SUB
    …                       ;返回点
    SUB  …                       ;子程序入口
    MOV   PC,R14            ;执行完返回
    例3:执行循环。
    MOV   R0,#10             ;设置循环次数
    LOOP …
    SUBS  R0,#1              ;循环次数减1
    BNE   LOOP                ;如果循环次数不为0,继续循环
    …                        ;否则结束循环

    2  转移交换、转移带链接和交换指令BX,BLX
    功能:BX、BLX指令用来支持者Thumb指令集,可以全处理器由ARM指令转向Thumb指令或者由于某种原因Thumb指令返回到执行ARM指令。

    格式:
    (1)B{L}X{<条件码>}寄存器Rm
    (2)BLX<Label>
    其中:
    RM   含有转移地址的寄存器。Rm的位[0]不用来作为地址的一部分。若Rm的位[0]为1,则指令将CPSR中的标志T置位,且将目标地址的代码解释为Thumb代码。若Rm的位[0]为0,则位[1]就不能为1。

    注释:
    在指令格式中,寄存器Rm中可以存放转移地址的值,如果Rm中的第0位为1,处理器将Thumb指令;如果为0,执行ARM指令。
    在指令格式2中偏移地址量的计算与B或BL指令相同。
    BLX指令有如下用法:
    l将下一条指令的地址拷贝到R14中(LR,链接寄存器)。
    l转移到Label或Rm中的地址。
    l若下面的两条中的任何一条成立,则指令集切换到Thumb,即
      -Rm的位[0]为1;
      -使用“BLX Label“形式。
    机器级的“BLX Label“指令不能转移当前指令±32MB范围之外的地址BLX指令格式1可以是条件或者无条件执行,而指令格式2是无条件执行。
    例1:无条件转移。
    BX     R0                      ;按R0内容转移
    ;如果R[0]为1,转Thumb状态
    例2:Thumb子程序调用。
         CODE32                  ;ARM代码

    BLX TSUB                ;Thumb代码执行
    TSUB   …                      ;Thumb指令TSUB子程序
    BX  R14                 ;返回ARM代码

    3.2.6  ARM协处理器类指令
    ARM协处理器指令完成与协处理器有关的操作,如协处理器内部寄存器之间的数据传送、协处理器与存储器之间的数据传送、协处理器与CPU寄存器之间的数据传送。这些指令依赖于使用特写的协处理器。协处理器设计者可以自由地按需要设计处理器的功能,而且这些指令通常借助于汇编器。
    1CDP和CDP2指令(CDP,Coprocessor Data operation)
    功能:完成协处理器寄存器数据操作。

    格式:CDP{条件码} CP#,opcodel,CRd,CRn,CRm{,opcode2}
         CDP2        CP#,opcodel,CRd,CRn,CRm{,opcode2}
    其中:
    CP#               指令操作的协处理器名。标准名为pn,n为0~15范围内的整数。
    Opcode1           协处理器的特定操作码。
    CRzn,CRm,CRn    协处理器寄存器。
    Opcode2           可选的协处理器特定操作码。

    注释:
    CDP2指令设置条件码为0b1111,为协处理器设计者提供额外的opcode空间。CDP2指的是适用于ARM v5指令系统及以上版本。
    例:
    CDP  p1,10,C1,C2,C3        ;协处理器1中的处理器C2和C3完成操作10然后
                              ;将结果放在C1中
    CDPEQ   p2,5,C1,C2,C3      ;如果Z位置1,那么协处理器2中的C2和C3完成
                              ;操作5(子操作2),然后将结果放在C1中

    2  LDC和STC指令
    功能:在存储器和协处理器之间传送数据。

    格式:
    (1)  零偏移格式
    LDC|STC{<条件码>}{L}<CP#>,CRd,[Rn]
    (2)  前变址格式
    LDC|STC{<条件码>}{L}<CP#>,CRd,[Rn,#offset]{!}
    LDC2|STC2{< CP#>>},CRd, [Rn,#offset]{!}
    (3)  后变址格式
    LDC|STC{<条件码>}{L}<CP#>,CRd,[Rn],#offset
    LDC2|STC2{< CP#>>},CRd, [Rn],#offset
    其中:
    L      可选后缀,指明是长整数传送。
    CP#    指令操作的协处理器名。标准名为pn,其中n为0~15范围内的整数。
    CPd    用于读取或存储的协处理器寄存器。
    Rn     存储器基址寄存器。若指定R15,则使用的值是当前指令地址加8。
    Offset 偏移量,其值必须为4的整倍数,范围在0~1020之间。

    注释:
    LDC2和STCC2指令设置条件码条件码为b1111,为协处理器设计者提供额外的opcode空间。LDC2和STC2指令适用于ARM v5指令系统及以上版本。注意:LDC2和STC2始终是无条件的。
      例1:
      LDC    p6,CR1,[R4]                   ;将存储器中的内容取至协处理器6
    ;寄存器CR1中R4为所以内容地址
      例2:
      LDC    p6,CR4,[R2,4]               ;将存储器中的内容取至协处理器6
    ;寄存器CR4中R2+4为所以内容地址
      例3:
      STC    p8,CR8,[R2,#4]!             ;将协处理器8寄存器CR8中的内容存
    ;至存储器中R2+4为所存内容的地址
    ;然后,R2=R2+4
      例4:
      STC   p6,CR9,[R2],#-16             ;将协处理器6寄存器CR9中的内容存
    ;至存储器中R2为所存内容的地址
    ;然后,R2=R2-16
    3  MRC、MRC2、MCR和MCR2指令
    功能:在协处理器与ARM寄存器之间传送数据。

    格式:
    (1)从协处理器传送至ARM寄存器
    MRC{<条件码>}<CP#>,<Opcode1>,Rd,CRn,CRm{,<Opcode2>}
    MRC2 <CP#>,<Opcode1>,Rd,CRn,CRm{,<Opcode2>}
    (2)从ARM寄存器传送至协处理器
    MCR{<条件码>}<CP#>,<Opcode1>,Rd,CRn,CRm{,<Opcode2>}
    MRC2 <CP#>,<Opcode1>,Rd,CRn,CRm{,<Opcode2>}
    本组指令格式中所有操作数的含义同(CDP和CDP2)。

    注释:
    MRC2和MCR2指令设置条件码为0b1111,为协处理器设计者提供额外的操作码字段。MRC2和MCR2指令适用于ARM v5指令系统及以上版本。注意:MRC2和MCR2始终是无条件的。
    例1:
    MRC    p15,R4,C0,C2,3             ;协处理器15中的寄存器C0和C2完成
    ;操作5(子操作3),然后将结果传到
    ;CPU寄存器4中
    例2:
    MCR    p14,1,R7,C7,C12,6        ;协处理器14在CPU寄存器7中完成
                               ;操作1(子操作6,然后将结果传到协
    ;处理器14的寄存器C12中
    4  MCRR和MRRC指令
    功能:在2个ARM寄存器和协处理器之间进行数据传送。

    格式:
    MRRC{<条件码>}<CP#>,<Opcode1>,Rd,CRn,CRm
    MCRR{<条件码>}<CP#>,<Opcode1>,Rd,CRn,CRm
    本指令格式中所有操作数的含义同本小节第1条指令(CDP和CDP·)。MCRR和MRRC指令适用于ARM v5TE指令系统及以上版本。

    3.2.7  ARM杂项指令
    1  状态寄存器传送至通用寄存器类指令
    功能:将状态寄存器的内容传送至通用寄存器。

    格式:
    MRS{<条件码>}Rd,CPSR}SPSR
    其中:
    Rd      目标寄存器,Rd不允许R15。
    R=0     将CPSR中的内容传送目的寄存器。
    R=1     将SPSR中的内容传送至目的寄存器。

    注释:
    MRS与MSR配合使用,作为更新PSR的读-修改-写序列的一部分。例如:改变处理器或清除标志Q。注意:当处理器在用户模式或系统模式下,一定不能试图访问SPSR
    这条指令不影响条件码标志。
    例:
    MRS   R0,CRSR              ;将CPSR中的内容传送至R0
    MRS   R3,SPSR              ;将SPSR中的内容传送至R3

    2  通用寄存器传送至状态寄存器传送指令
    功能:将通用寄存器的内容传送至状态寄存器。

    格式:
    MSR{<条件码>CPSR_f|SPSR_f,<#ommed_8r>
    MSR{<条件码>CPSR_<field>|SPSR_<field>,Rm
    其中:
    <field>字段可以是以下之一或多种:
    lC:控制域屏蔽字段(PSR中的第0位到第7位);
    lX:扩展域屏蔽字段(PSR中的第8位到第15位);
    lS:状态域屏蔽字段(PSR中的第16位到第32位);
    lF:标志域屏蔽字段(PSR中的第24位到第31位)。
    immed_8r  值数字常量的表达式。常量必须对应8位位图。该位图在32位字中循环移位偶数数位。
    Rm        源寄存器。

    注释:
    同前一条指令(MRS)。
    例1:设置N、Z、C、V标志。
    MSR    CPSR_f,#&f0000000            ;仅高位有效,其他必须为0
    例2:
    仅置位C标志,保留N、Z、V标志。
    MRS    R0,CPSR                    ;将CPSR中的内容传送至R0
    ORR    R0,R0,#&1f                ;置位R0的第29位
    MSR    CPSR_c,R0                   ;再将R0中的内容传送至CPSR

    3  软件中断指令SWI
    格式:
    SWI{<条件码>immed_24
    其中:
    immed_24               表达式,其值范围为0~ -1的整数(24位整数)。

    注释:
    (1)  SWI指令用来执行系统调用,处理器进入管理模式,并从地址0x08开始执行指令<24位立即数>并不影响指令的执行,由系统所解释。CPSR保存到管理模式的SPSR中执行转移到SWI向量。
    (2)  条件码标志。这条指令不影响条件码标志。
    例1:输出字符“A”
    MOV    R0,#“A”                   ;从R0中得到“A”
    SWI  SWI_WriteC                          ;然后显示
    例2:通过SWI指令输出字符串

    BL   STROUT                         ;输出如下信息
    =   “Hello World”,&0a,&0d,0
    …                             ;返回
    STROUT LDRB   R0,R[14],#1            ;得到字符
    CMP    R0,#0                 ;检查结束标记
    SWINE  SWI_WriteC             ;如果没有结束,则继续
    BNE    STROUT                 ;…循环
    ADD    R14,#3                ;字对齐
    BIC    R14,#3
    MOV    PC,R14                ;返回
    例3:结束用户程序返回监控程序
    SWI     SWI _Exit              ;返回


    4  断占指令(v5T)
    格式:
    BKPT immmed_16
    其中:
    immmed_16     表达式,基值范围为0~65536内的整数(16位整数)。

    注释:
    支持软件调试,执行时中断正常指令,进入相应的调试子程序。BKPT指令适用于ARM  v5指令系统及以上版本。
    例:
    BKPT

    3.3  Thumb指令系统
    并非所有的ARM处理器都可以执行Thumb指令,在指令集名中,含有T的均可执行Thumb指令,如ARM7TDMI。
    CPSR中的T标志决定是执行Thumb指令还是ARM指令,如置位,执行Thumb指令,否则执行ARM指令。
    ARM在复位以后,执行ARM指令。通常至Thumb指令的执行是由一条转移和交换指令完成的,如BX指令。但是例程处理程序中如果使用数据处理指令或者多寄存器调用指令,也会转移到Thumb指令中去。如果例程处理完毕,也将返回ARM指令中。
    必须明确的是Thumb指令系统必须包括ARM代码,至少是初始化和例程入口部分。
    Thumb指令集是ARM指令集的子集,Thumb只使用有限的ARM寄存器。Thumb指令一般可以完全访问通用寄存器R0~R7(称为低寄存器),R13用作堆栈指针,R14用作链接寄存器,R15用作PC。Thumb中的一些指令可以访问其余的寄存器如R8~R15(称为高寄存器),算术运算和逻辑运算指令可以访问CPS2中的标志位。
    大部分的Thumb 指令与ARM指令类似,不过在寄存器、立即数、寻址等方面会有些差异,Thumb和ARM指令性计划集的区别一般有以下几点:
    l转移指令;
    l数据传送指令;
    l单寄存器Load和Store指令;
    l多寄存器Load和Store指令。
    Thumb指令集没有协处理器指令、信号量(samaphore)指令以及访问CPSR或SPSR的指令。

    (1)  转移指令
    转移指令用于:
    l向后转移形成循环;
    l条件结构向前转移;
    l转向子程序;
    l处理器从Thumb状态切换到ARM状态。
    程序相对转移,特别是条件转移与在ARM状态下相比,在范围上有更多的限制,转向子程序只能是无条件转移。
    (2)  数据处理指令
    这些指令对通用寄存器进行操作,在许多情况下,操作的结果必须放入其中一个操作数寄存器中,而不是第3个寄存器中。数据处理操作比ARM状态更少,访问寄存器R8~R15受到一定限制。
    MOV或ADD指令可访问寄存器R8~R15,数据处理指令总是更新CPS2中的ALU状态标志。访问寄存器R8~R15的Thumb数据处理指令不能更新标志。
    (3)  单寄存器Load和Store指令
    这些指令从存储器读取1个寄存器值,或把1个寄存器值存储到存储器。在Thumb状态下,这些指令只能访问寄存器R0~R7。
    (4)  多寄存器Load和Store指令
    LDM和STM将任何范围为R0~R7的寄存器子集从存储器读取以及存储到存储中。
    PUSH和POP指令使用堆栈指针(R13)作为基址实现满递减堆栈。除可传送R0~R7外,PUSH还可以用于存储连接寄存器,POP可以用于读取程序指针。
    Tuhmb指令主要有以下几类指令组成:Tuhmb Load/Store类指令;Thumb数据运算类指令;Thumb转移类指令,以及软件中断指令。

    3.3.1  Thumb Load/Store类指令

    1  Thumb单寄存器Load/Store指令
    Thumb单寄存器传送类指令是ARM单寄存器传送类指令的一个子集,和ARM有相同的指令格式。
    Thumb单寄存器传送指令分以下4种:
    (1)  LDR和STR—立即数偏移
    功能:读取寄存器和存储寄存器。寄存器的地址用一个寄存器的数偏移量指明,立即数偏移的半字和字节读取是无符号的。

    格式:
    <操作码>Rd,[Rn,<#immed_5*N>]
    <操作码>包括:LDR,LDRB,STR,STRH和STRH指令
    其中:
    H        指明无符号半字传送。
    B        指明无符号字节传送
    RD       读取和存储寄存器。Rd必须在R0—R7范围内
    RN       基址寄存器.Rn必须在R0—R7范围内
    Immed_5*N    偏移量。Immed_5是一个表达式,其中值在0--31范围内,在汇编时结果是的N倍数.
    对字节传送,N=1
    对半字传送,N=2az
    对字传送, N=4

    注释:
    字传送的地址必须可被4整除,半字传送的地址必须可被2整除.
    若系统中有系统协处理器(CP15),则可允许对准检查。若允许对准检查,则非对准的传送会引起对准异常
    若系统没有协处理系统器(CP15)或禁止对准检查,则:
    非对准读取使Rd不可靠
    非对准存使存储器的2个或4个字节不可靠。对半字存储,不可靠的存储器位置是address AND NOT 0x1; 于字存储器,则是address AND NOT 0x3
    例:
    LDR  R3,[R5,#0]    ;(R5)→R3
    STRB  R0,[R3,#3]      ;(R0)→((R3)+31)
    STRH  R7,[R3,#16]       ;(R7)→((R3)+16)
    LDRH  R2,[R4,#Label—{PC}]

    (2)  LDR和STR---寄存器偏移
    功能:读取寄存器和存储寄存器。存储器的地址用一个寄存器的基于寄存器偏移指明存储器地址。

    格式:
    《操作码》Rd,[Rn,Rm]
    《操作码》是下列情况之一:
    读取寄存器,4字节字
    存储寄存器,2字节字
    读取寄存器,2字节无符号半字
    读取寄存器,2字节字有符号半字,有符号位扩展(即高位字节与符号字节相同)
    存储寄存器,2字节半字
    读取寄存器,无符号半字
    读取寄存器,有符号半字,有符号位扩展(即高位字节与符号位相同)
    存储寄存器,字节
    含偏移量的寄存器,Rm必须在R0~R7范围内

    注释:
    同3.3.1节第1条指令。
    例:
    LDR  R2,[R1,R5];  ((R1)+(R5))---R2
    STRH  R0,[R0,R1];  (R0)---((R0)+(R1))
    STRB  R1,[R7,R0];  (R1)---(R7)+(R0)

    (3)  LDR----PC相对偏移
    功能:读取寄存器和存储器。存储器中的地址用中内容的立即数偏移指明。字节码结构:

    格式:
    LDR  Rd,[PC,#immed_8*4]
    LDR  Rd,Label
    其中:
    immed_8*4偏移量。它是一个表达式,取值(在汇编时)为4的整数倍,范围在0~1020内。
    Label  程序相对偏移表达式。必须在当前指令之后且范围内。

    注释:
    同3.3.1节第1条指令
    例:+
    LDR   R2,[PC,#1016];   ((PC)+1026)---R2
    LDR   R5,localdata

    (4)  LDR和STR---SP相对偏移
    功能:读取寄存器和存储寄存器。存储器的地址用中内容的立即数偏移指明。

    格式:LDR  Rd,[SP,#immed_8*4]
      STR    Rd,[SP,#immed_8*4]
    其中:
    immed_8*4
    偏移量。它是一个表达式,取值(在汇编时)为4的整数倍,范围在0~1020内。

    注释:
    同3.3.1节第1条指令。
    例:
    LDR  R0,[SP,#920];  ((SP)+920)---R0
    STR  R1,[SP,#20];  (R1)---(SP)+20

    2  Thumb多寄存器指令
    功能:Load和多个Store寄存器

    格式:(1)LDMIA  Rn!,  <Reglist>   (2)STMIA  Rn!,<Reglist>
    其中:
    Reglist    低寄存器或低寄存范围的,用逗号隔开的列表。列表中至少有一个寄存器。
    Rn  目的寄存器,必须是低于寄存器

    注释:
    (1)寄存器以数字顺序取或存储。最低数字的寄存器在的初地址中。的值以中寄存器个数的4倍增加。
    (2)若在Rn寄存器列表中,则
    对于LDMIA指令,Rn的最终值是读取的值,不是增加后的地址。
    对于STMIA指令,Rn的终值有如以下两种情况:
    ---若是寄存器列表中最低的寄存器,则的存储值为初值;
    ---其他情况则不可预知。
    例:
    LDMIA   R3!,(R0,R4);   (R0)---(R3),(R4)---(R3)+4;    (R3)+8---R3
    STMIA   R0!,(R3,R5,R7);((R0)--R3,((R0)+4)---R5,
             ;((R0)+8)---R7,(R0)+12---R0

    3  堆栈指令
    功能:低寄存器和可选的LR进栈,低寄存器和可选的PC出栈。

    格式:POP   {《REglist》{,PC}}
        PUSH  {<Reglist>{,LR}}
    其中:Reglist
    低寄存器或寄存器范围的,用逗号隔开的列表。

    注释:
    (1)Thumb堆栈是满递减堆栈,向下增长,且SP指向堆栈的最后入口。
    (2)寄存器以数字顺序存储在堆栈中。最低数字的寄存器其地址最低。
    (3)POP{Reglist}这条指令引起处理器转移到从堆栈弹出给PC的地址,这通常是从子程序返回,其中LR在子程序开头压进堆栈。
    (4)对于ARMv5T及以上的版本,则
    若读到PC中的值的位[1:0]是b00,则处理器变换到ARM状态
    位[1:0]不允许的值b10。
    (5)条件码标志。这些指令不影响条件码标志。
    例:
    PUSH   {R0,R4---R7}  ;R0,R4---R7进栈-
    PUSH   {R0,LR}
    POP    {R2,R5}
    POP  {R0---R7,PC}

    3.3.2  Thumb数据运算类指令
    Thumb数据运算指令有以下8种:
    1  ADD和SUM-----低寄存器
    功能:2个寄存器的,内容相加或相减,结果放到第3个寄存器中。

    格式:<操作码>Rd,Rn,Rm
     <操作码>包括:ADD,SUB指令。
    其中:
    Rd  目的寄存器。必须是低寄存器
    Rn   第操作寄存器。必须是低寄存器
    Rm   第2操作寄存器。必须是低寄存器。

    注释:这些指令更新标志N,Z,C,V。
    例:ADD   R3,R1,R5。
    2  ADD和SUB----小整数
    功能:寄存器中的值加上或减去一个小整数,结果放在另一个不同寄存器中。

    格式:<操作码> Rd,Rn,# <3位立即数>
    <操作码>包括:ADD,SUB指令。
    其中:
    Rd目的寄存器。必须是低寄存器(R0~R7)
    Rn第1操作数寄存器。必须是低寄存器(R0~R7)
    Expr3  表达式,为取值范围在—7~+7内的整数。
    注释:
    这些指令更新标志N,Z,C,V.
    例:SUB   R0,R4,#5   ; (R4)---5---R0

    3  ADD,SUB,MOV,CMP----大整数
    功能:寄存器中的值对于一个大事整数进行ADD,SUB,MOV,CMP运算,结果放在另一个不同的寄存器中。

    格式:
    <操作码>  Rd|Rn,#<8位立即数>
    <操作码>包括:ADD,SUB,MOV,CMP指令。
    其中:
    Rd,Rn  目的寄存器。必须是低寄存器(R0~R7)
    Expre8  表达式,为取值范围在—255~+255内的整数。

    注释:这些指令更新标志N,Z,C,V.
    例:
    ADD  R7,#201
    ADD  R1,vc+4  ;   vc+4汇编时必取值范围为—255~+255的整数

    4  ADD,MOV,CMP----高或低寄存器
    功能:将寄存器中值进行运算,结果送回到第一操作数寄存器。

    格式:
    <操作码> Rd|Rn,Rm
    <操作码>包括:ADD,MOV,CMP指令。
    其中:
    Rd,Rn目的寄存器,也是第1操作数寄存器。
    Rm第二操作数寄存器。
    Rd,Rn,Rm使用高或低寄存器,当和是低寄存器,指令“ADD,Rd,Rm”汇编成“ADD Rd,Rm”。
    注释:
    若Rd,Rn和Rm是低寄存器,则更新条件码标志N,Z,C和V,其他情况下这些标志不受影响。
    例:ADD  R0,R8
    ADD  R2,R4 ;   等价于“ADD  R2,R2,R4”,不影响标志。

    5  ADD和SUB----SP
    功能:SP加上或减去立即数常量。

    格式:
    <操作码>SP,#<expr>
    <操作码>包括:ADD,SUB指令。
    其中:
    expr表达式,取值范围在—508~+508内的4倍数的整数。expr为负值的ADD指令汇编成相应的带正数常量的指令。expr为负值的指令汇编相应的带正数常量的ADD指令。

    注释:
    这条指令指示不影响条件码标志。
    例:
    ADD  SP,#312
    SUB   SP,#96
    SUB   SP,#abc+8;  abc+8汇编时必须取值为范围在---508~+508内4的整数倍。

    6  ADD---PC或SP相对偏移
    功能:SP或PC值加上一立即相对数常量,结果放入低寄存器。

    格式:
    ADD   Rd,Rp,#<expr>
    其中:
    Rd   目的寄存器。Rd必须在R0~R7范围内。
    Rp  SP|PC.RP是PC,则使用值是(当前指令地址+4)AND&FFFFFFC。
    Expr  表达式,取值为范围在0~1020的4整倍数。

    注释:
    这条指令不影响条件码标志。
    例:
    ADD  R2,SP,#64
    ADD  R6,PC,#980
    ADD  R0,PC,#lit—{PC}; lit—{PC}必须取值成范围在0~1020的4的
    ;整数倍

    7  ASR,LSL,LSR和ROR运算
    功能:移位和循环移位操作。这些指令可使用寄存器中的值或立即数移位。

    格式1:
    <操作码>Rd,Rn,<#immed_5>
    其中:
    <操作码>是下列的任何一种:
    ASR算术右移。将寄存器中的内容看作补码形式的有符号整数。将符号位移拷贝到空位。
    LSL逻辑左移,移入为0。
    LSR逻辑右移,移入为0。
    ROR循环右移。将寄存器右移出的位循环移回到左端。ROR仅能与寄存器控制的移位一起使用。
    Rd立即数移位的目的寄存器。必须在R0~R7范围内。
    Rn立即数移位的源寄存器。Rn必须在R0~R7范围内。
    Immed_5  立即数移位量。它是一个取值为整数的表达式。整数的范围如下:
    <操作码>若是LSL,ROR,则为0~31;
    其余则为1~32。
    格式2:
    <操作码> Rd|Rn,Rs|Rm
    其中:
    <操作码>同格式1。
    Rd 寄存器控制移位的源寄存器。Rd必须在R0~R7范围内。
    Rs 在控制移位中包含移位量的寄存器。Rs必须在R0~R7范围内。

    注释:
    (1)立即数移位(格式1)。
    指令从Rn取值,并对其进行移位,结果放回Rd中。
    (2)寄存器控制移位(格式2)
    这些指令从Rd中取值,并对其进行移位,结果放回Rd.只有Rs的最低的效数字节可用作移位量。
    对于除ROR以外的所有指令,则有
    若移位量为32,则Rd清零。最后移出的位保留在标志C中。
    若移位量大于32,则Rd和标志C均被清零。
    (3)条件码标志
    这些指令根据结果更新标志N与Z,且不影响标志V。对于标志C,若移位量是零,则它不受影响,其他情况下,它包含源寄存器的最后移出位。
    例:ASR R3,R5
    LSR  R0,R2,#6
    LSR  R%,R5,av; av的值必须在汇编时取成在1~32范围内的整数
    LSL  R0,R4,#0 ;除了不影响标志C和V外,同“MOV R0,R4”

    8  其他运算类指令
    格式1:
    <操作码>  Rd|Rn,Rm|Rs
    <操作码>  包括:MOV,MVN,CMN,TST,ADC,SBC,NEG,MUL,AND,EOR,ORR,BIC指令。
    <操作码>Rd|Rn,#expr
    <操作码>包括:MOV,CMP指令。

    Rd  Rn 目的寄存器,它也是包含第1条指令操作数。
    Rm  Rs  第二操作数寄存器。
    Expr  表达式,其值范围为在1~255内的整数。
     
      表3~5  Thumb数据处理指令
    助记符含义动作
    ADC  Rd,RmADD  Rd,Rn,RmADD Rd,Rn,#0to7ADD Rd,#0to255AND Rd,RmASR Rd,Rm#1to32ASR Rd,RaBIC Rd,RaCMN Rn,RmCMP Rn,#0to255CMP Rn,RmEOR Rd,RmLSL Rd,Rm,#0to31LSL Rd,Rm,#1to32LSR Rd,Rm,#1to32LSR Rd,RsMOV Rd,#0to255MOV Rd,RnMUL Rd,RmMVN Rd,RmNEG Rd,RmORR Rd,RmRORRd,RsSBC Rd,RmSUBRd,Rn,RmSUB Rd,Rn,RmSUB Rd,#0to255TST Rn,Rm带进位加法加法加法加法逻辑与算术右移算术右移位清除比较非值比较比较逻辑异或逻辑左移逻辑左移逻辑右移逻辑右移传送传送乘法传送非取负逻辑或循环右移带进位减法减法减法减法测试Rd---Rd+Rm+进位标志Rd---Rn+RmRd---Rn+3位立即数Rd---Rd+8位立即数Rd---Rd AND RmRd---Rm ASR5位立即数Rd---Rd ASR RsRd---Rd AND NOT RmRn+Rm更新标志Rn—8后立即更新标志Rn—RmRd---Rd EOR RmRd---Rm LSL 5位立即数Rd---Rm LSL RsRd---Rd LSR 5位立即数Rd---Rd LSR RsRd---8位立即数Rd---RnRd---Rm*RdRd---NOT RmRd---0--RmRd---Rd OR RmRd---Rd ROR RsRd--Rd-Rm-NOT(进位标志)Rd---Rn--RmRd---Rn—3位立即数Rd---Rn—8立即数Rn AND Rm后更新标志

    注释:
    (1)除了“CMP RN,Rm”和“MOV Rd,Rm”指令中的和可以是中的Rn,Rm任何寄存器外,其余指令只能使用低寄存器(R0~R7)
    (2)条件码标志:
    ADC,SBC,CMP,CMN和NEG指令更新标志N,Z,C和V.
    AND,EOR,ORR,BIC指令根据结果更新标志N和Z
    MVN,TST,“MOV Rd,#expr”和指令更新标志N和Z,对标志C和V影响。
    “MOV Rd,Rm”指令表现如下:
    若Rd或Rm是高寄存器(R8~R15),则标志不受影响。
    若Rd或Rm都是低寄存器(R0~R7),则更新标志N和Z,且清除清除标志C和V。
    MUL更新标志N和Z。在ARM v4及前版本中,MUL会使标志C和V不可靠。在ARM v5及以后的版本中,MUL不影响标志C和V。
    注意:可用移位为0来使用LSL,实现在低寄存器之间传送而不清除标志C,V。
    例:
    ADC  R2,R4
    CMP   R7,R12 ;  指令“CMP  Rn,Rm”允许高寄存器
    MOV  R3,#0
    TST   R2,R4

    3.3.3  Thumb转移指令
    Thumb  转移指令主要分以下几类:

    1  B指令
    格式1:
    B  <条件码> <Label>

    格式2:
    B  <Label>
    其中:
    Label  程序相对偏移表达式。通常是在同一代码块内标号。
    若使用条件码,则必须在当前指令的—254~+254字节范围内;
    若指令是无条件,则Label必须中正负2KB范围内。
    Thumb B指令的条件码如表3--6所示。

    表3—6  Thumb  B指令
    条件代码含义标志位状态显示
    EQNECS/HSCC/LOMIPLVSVCHILSGELTGTLE相等/是否为0不等进位置/大于进位清零/小于结果为负结果为正溢出无溢出大于小于大于等于小于等于大于小于等于 Z置位Z清零C置位C清零N置位N清零V置位V清零C置位且Z清零C清零或Z置位N等于VN不等于VZ清零或N等于VZ置位或N不等于V
    注释:
    若条件码满足或不使用条件码,则B指令引起处理器转移到Label.
    例:
    B  dloop
    BEQ   sectB

    2  BL,BLX指令
    格式:
    BL{X}  <Label>
    其中:
    Label  程序相对转移表达式。

    注释:
    BL指令将下一条指令的地址拷贝到R14(LR链接寄存器),并引起处理器转移到Label。机器级指令不能转移到当前正负4MB指令以外的地址。必要时,ARM链接器插入代码(veneer)以允许更长的转移。
    BL指令实际上分为2条指令,1条指令H=0,它把11位偏移量左移12位,加上现行PC,写入中R14(LR),另一条指令H=1,它把LR加上11位偏移量乘2写入PC,同时把下一条指令写入R14中。
    BLX指令可用于:
    拷贝下一条指令的地址到R14(LR链接寄存器)。
    引起处理器转移到Label或Rm存储的地址
    如果Rm的位[0]清零,或使用“BLX Label”形式,则指令集切换到ARM状态。BLX指令适用于ARM v5T指令系统及以上版本。
    例:
    B   extract

    3  BX,BLX指令
    格式:
    B{L}X   Rm
    其中:
    Rm  装有目的地址的ARM寄存器,m=0~15。Rm的位[0]I不用于地址部分。若Rm位清零。则
    位[1]也必须清零;
    指令清零CPSR中的标志T,目的地址的代码被解释为ARM代码。

    注释:
    BX指令引起处理器转移到Rm存储的地址。若Rm的位[0]置位,则指令集切换到Hhnmb状态。
    BLX指令用来在Thumb程序中调用ARM或者子程序,地址由Rm指定。从子程序返回,用BX  R14指令。
    例:
    BX  R5
    BLX  R6

    3.3.4  Thumb软件中断和断点指令
    1  Thumb软件中断指令
    功能:Thumb的SWI指令类似于ARM SWI指令。该指令执行后的操作是:
    (1)将下一条Thumb指令地址保存进R14_svc。
    (2)PSR的内容保存进SPSR_svc;
    (3)禁止IRQ中断,清除Thumb位,进入SVC模式;
    (4)PC指向0x08。
    返回指令恢复Thumb执行的状态。
    格式:SWI  <immed_8>
    其中:
    immed_8 符号表达式,其取值范围为的整数。
    SWI指令引起SWI异常。这意味着处理器状态切换到ARM态,处理器模式切换到管理模式的,CPSR保存到管理模式中,执行转移SWI到向量地址。
    处理器忽略immed_8,但immed_8出现在指令操作码的位[7:0]中。而异常处理程序用它来确定正在请求何种服务。
    注释:
    这条指令不影响条件码标志。
    例:
    SWI  12

    2  Thumb断点指令
    格式:
    BRKT  immed_8
    其中:
    immed_8 符号表达式,取值范围为0~255的整数。

    注释:
    BKPT(BreakPoinT)指令引起处理器进入调试模式。调试工具利用这一特点调查到达特定地址的指令时的系统状态。
    尽管immed_8出现在指令操作码的位[7:8]中,处理器忽略immed_8。调试器用它来存储有关断点的附加消息。
    BKPT指令适用于ARM v5T指令系统及以上版本。
    例:
    BKPT  67
    BKPT  2_10110

    3.3.5  Thumb指令示例
    1  从Thumb状态到ARM状态
    ADR  R1,oct  of  Thumb
    MOV  R11,R1
    BX    R11
    ……
    ALIGN
    CODE32
    Out  of  Thumb  ……

    2  ARM和Thumb指令编写的比较
    本节最后通过比较ARM和Thumb指令编写“Hello Word”程序,示例Thumb指令的编写。从下面的例子中可以看到,指令Thumb的执行必须由ARM状态转向Thumb状态,通常BX指令完成。另外在Thumb指令前必须有CODE16伪指令指示汇编器以下指令为Thumb指令。
    (1)  ARM指令编写的“Hello  Word”程序
    AREA   HelloW,CODE,READONLY
    SWI_WriteC   EQU &0;  SWI中断入口
    SWI_Exit     EQU &11
    ENTRY
    START   ADR   R1,TEXT
    LOOP    LDRB   R0,[R1],#1
    CMP   R0,#0
    SWINE   SWI_WriteC;参数&0完成显示成输出
    BNE   LOOP
    SWI   SWI_Exit;参数&11返回
    TEXT   =    “Hello  Word”;&0a,&0d,0
    END
    (2)  Thumb指令编写的“Hello  Word”程序
    AREA   HelloW_Thumb,CODE,READONLY
    SWI_WriteC    EQU&0
    SWI_Exit       EQU&11
           ENTRY
           CODE32  ;指示以下为ARM指令
           ADR      R0,START+1
           BX        R0  ;转向Thumb程序
           CODE16        ;指示以下指令为Thumb指令
    START   ADR    R1,TEXT
    LOOP    LDRB    R0,[R1]
    ADD    R1,R1,#1
    CMP    R0,#0
    BEQ     DONE    ;转向Thumb子程序DONE
    SWINE   SWI_WriteC
    B        LOOP
    DONE    SWI      SWI_Exit
           ALIGN
    TEXT    DATA
            =    “Hello World”,&0d,0
           END    

    3.4  ARM宏汇编
    本节将详尽地介绍汇编器所提供的特征,包括伪指令,宏汇编以及指示标志。
    3.4.1  预定义变量
    1  预定义变量的寄存器的协处理器名
    ARM汇编器对ARM的寄存器进行了预定义,所有的寄存器和协处理器都是大小写敏感的。预定义的寄存器如表3—7所示。
    (1)  定义的寄存器名
    R0~R15
    R0~r15
    a1~a4
    v1~v8
    sp和SP
    Ir和LR
    Pc和PC
    Sl和SL



    表3---7为ARM寄存器列表及含义
    寄存器特殊定义其它定义含义
    R15R14R13R12R11R10R9R8R7R6R5R4R3R2R1R0V8V7V6V5V4V3V2V1a4a3a2a1PCLRSPIPFPSLSBWR程序计数器链接寄存器堆栈指针程序调用暂存寄存器变量寄存器8/帧指针(ARM状态)变量寄存器7/堆栈上限指针(ARM)变量寄存器6/基址寄存器(进程ID/重入/共享库中)变量寄存器5变量寄存器4(Thumb状态工作寄存器)变量寄存器3变量寄存器2变量寄存器1参数/结果/暂寄存器4参数/结果/暂寄存器3参数/结果/暂寄存器2参数/结果/暂寄存器1
    R0~R3通常用来传递参数和保存结果,也可以保存子程序调用的中间结果,在ARM状态下,R12(也称为IP)通常也保存子程序调用的中间结果。R14~R11通常保存程序的局部变量,也可以用V1~V8表示,但是V1~V4只能在Thumb状态下使用。
    R12~R15一般有特殊用途,也通常称为IP,SP,LR,PC。
    (1)定义的程序状态寄存器名
    cpsr和CPSR
    spsr和SPSR
    (2)定义的浮点数寄存器名
    f0~f7
    F0~F7
    (3)定义的协处理器名
    p0~p15
    c0~c15

    2  内置变量
    表3—8列出了ARM汇编器所定义的内置变量,值得注意的是内置变量的设置不能用SETA,SETL,或SETS等表示词来设置,只能用字符或条件表达式来设置。例如:
    IF   {ARCHITECTURE}=“4T”
    表3—8  变量含义
    (PC )或者(VAR)或者@(TRUE)(FALSE)(OPT)(CONFIG)(ENDIAN)(CODESIZE)(CPU)(ARCHITECTURE)(PCSTOREOFFSET)当前指令的地址存储区计数器的当前值逻辑常量为真逻辑常量为假当前设置列表选项,OPT用来保存当前列表选项,改变选项值,恢复设置它的原始值如果汇编器在ARM模式下值为32,如果汇编在Thumb 模式下值为16如果汇编器在big—endian模式下为big,如果汇编器在某些方面little—endian模式下值为little如果汇编Thumb代码值为16,否则为32选定的CPU符号,如果没有说明,则为genericARM选定的ARM架构的值,3,3M,4,4T,4TxMSTRpc,[…]或STM  Rb,(…PC)的地址和PC的存储值之间的偏移量

    3.4.2  伪指令
    ARM汇编器采用两类伪指令,一类是为ARM伪指令,另一类是Thumb伪指令。在ARM状态下可以使用的伪指令如下:
    1  ADR伪指令
    功能:把程序相关的或寄存器相关的地址调进寄存器中。

    格式:ADR{condition} register,expression
    其中:
    register  读取的寄存器。
    Expression  程序相关的或寄存器相关的表达式,必须是:
    255字节以内的非字对准地址;
    1020字节以内的字对准地址。
    寄存器相关的表达式由1个寄存器加或减1个数字常数组成(见“ⅴ”或者MPA介绍。)程序相关的表达式由PC加或减1个数字组成,一般它可为标号或加减数字表达式。

    注释:
    ADR伪指令通常汇编成一条指令,汇编器产生一条ADD或SUB指令以读入地址。如果表达式是关于程序相关的,读取地址只能是ADR伪指令所在代码所在的地址。
    例:
    start   MOV  R0,#10
    ADR  R4,start    ; 等同于SUB,R4,PC,#0xc

    2  ADRL伪指令
    功能:与ADR功能类似,但是可以调进范围更广的地址。

    格式:
    ADR{condition} register,expression
    其中:
    register   读取的寄存器。
    Expression    程序相关的或相关的表达式,必须是:
    64KB以内的非对准地址;
    256KB以内的字对准地址。

    注释:
    ADRL伪指令通常汇编成2条指令,即使地址在第1条指令已经产生,也会产生1条冗余指令。如果表达式是关于程序表达式相关的,读取地址只能是ADRL伪指令所在的代码段所在的地址。注意:该指令只能在ARM状态下使用,在Thumb状态下不能使用。
    例:
    start MOV   R0,#10
    ADRL   R4,start+60000;等同于ADD  R4,PC,#0xE800
                          等同于ADD  R4,R4,#0x254

    3  LDFD伪指令
    功能:将一个双精度的浮点常量放进

    格式:
    LDFD{condition} fp-register,=expression
    其中:
    condition   可选的条件代码。
    fp-register  读取的浮点寄存器。
    Expression   浮点常量。汇编器通常把放在一个库中,用LDFD伪指令读进浮点寄存器中,该浮点常量用2个字存放。PC与该常量的偏移量不得超过4KB。

    注释:
    浮点数常量的范围是:
    最大值 1.79769313486231571e+308
    最小值2.22507385850720138e—308ADR
    注意;只有系统中有浮点加速器FPA(Floating Point Accelerator)时,才能使用该指令。
    例:
    LDFD  f1,=3.12E106

    4  LDFS 伪指令
    功能:将一个单精度的浮点数常量放进一个浮点数寄存器。

    格式:
    LDFS{condition} fp-register,=expression
    其中:
    condition  可选的条件代码。
    fp-register  读取的浮点寄存器。
    Expression  浮点常量。汇编器通常把该常量放在一个库中,用LDFD伪指令读进浮点寄存器中,该浮点常量用2个字存放。PC与该常量的偏移量不得超过4KB。

    注释:
    浮点数常理的范围是:
    最大值:3.40282347e+38F
    最小值:1.17549435e—38F
    注意:只有系统中有一个浮点加速器时,才能使用该指令。
    例:
    LDFS  f1,=3.12E---6

    5  LDR 伪指令
    功能:将一个32位常量或地址读取至寄存器。

    格式:
    LDR{condition} register,=[expression|Label-expression]
    其中:
    condition             可选的条件代码。
    register              读取的寄存器。
    expression            数字常量:
    如果该数字常量在MOV或MVN指令的范围中,汇编器会产生合适的指令;
    如果该数字量不在MOV或MVN指令的范围中,汇编器把该常量于程序后,用程序相关的LDR伪指令读取,PC与该常量的偏移量不得超过4KB。
    Label-expression      程序相关的或外部的表达式。汇编器将其存放在程序后的常量库(称为文字池(literal pool))中,用程序相关的LDR伪指令读取,PC与与该常量的偏移量不得超过4KB。
    注释:
    LDR伪指令的使用有两个目的:
         对于不能被MOV和MVN指令所读取的立即数,将其变成常量,进行读取:
         将一个程序相关的或外部的表达式读取进寄存器中.
    例:
    LDR  R1, =0xfff
    LDR  R2, =place

    6  NOP伪指令
    功能: 产生空操作代码.即:MOV R0,R0.

    格式:
        NOP

    注释:
    该指令不能带条件使用,也不能改变条件码.


    ARM汇编器在汇编时将伪指令转换成ARM或Thumb指令,在Thumb状态下可以
    使用的伪指令如下:
    1  ADR Thumb伪指令
    格式:
    ADR register, expression
    其中:
    register      读取的寄存器.
    Expression   程序相关的或寄存器相关的表达式,必须是4~1020字节以内的字对准地址,该地址必须在局部定义.

    注释:
    在Thumb状态下,ADR伪指令只能产生字对准的地址,通常使用ALIGN符号实现对准.如果表达式是关于程序相关的,读取地址只能是ADR伪指令所在的代码段所在的地址.
    例:
               ADR  R4,txampl
               ; code
    ALIGN
    Txampl      DCW     0,0,0,0

    2  LDR Thumb伪指令
    功能:将一个32位常量或地址读取低寄存器.

    格式:
    LDR   register,=[expression|Label-expression]
    其中:
    register              读取的寄存器,仅限于R0~R7.
    expression            数字常量:
    如果该数字常量在MOV指令的范围中,汇编器会产生合适的指令;
    如果该数字量不在MOV的范围中,汇编器把该常量于程序后,用程序相关的LDR伪指令读取,PC与该常量的偏移量不得超过4KB。
    Label-expression      程序相关的或外部的表达式。汇编器将其存放在程序后的常量库.
    程序相关的LDR伪指令读进,PC与该常量的偏移量不得超过1KB
    如果Label-expression是外部表达式,或者不包含在当前段,汇编器会在目标文件中设置一个链接重定位指示符.

    注释:
    LDR伪指令的使用有两个目的:
         对于不能被MOV和MVN指令所读取的立即数,将其变成常量,进行读取:
    将一个程序相关的或外部的表达式读取进寄存器中.
    例:
    LDR  R1, =0xfff
    LDR  R2, = labelname
    3  MOV Thumb伪指令
    功能:
    MOV   Rd, Rs
    其中:
    Rd           目的寄存器.
    Rs           源寄存器.

    注释:MOV伪指令汇编时即数为0的ADD指令。
    例:
    MOV  Rd,RS
    4  NOP伪指令
    功能:产生空操作代码。即:MOV  R8,R8

    格式:
    NOP

    注释:
    该指令不能带来条件使用,也不能改变条件代码。

    3.4.3  指示符
    1  AREA
    功能:指示汇编器汇编一段新的代码或新的数据区。

    格式;
    name  给出的特定段名。以数字开头,必须加竖线,否则,将报错,例如:|1_Data-Area|。某些名字已保留,如:|C$$code|已经被C编译器用作代码,或者用作与C库相连的代码段。
    Attr    段名属性,下列属性是有效的:
    ALIGN=expression
    缺省状态下,AOF段将按4个字节对准,expression可以是2~31之间的整数,该段将按2(上标为expression)字节对准。例如,espression等于10,该段将按1KB对准。
    CODE  特定机器指令,缺省为READONLY。
    COMDEF   通用段定义。该AOF段可能包括代码和数据,但必须与其他段名相区别。
    COMMON  通用数据段,无须再注释定义任何代码和数据,通常由链接器初始化为零。
    DATA   包含数据,但是不包含指令,缺省为READWRITE
    INTERWORK   表明代码段可以适用ARM/Thumb interworking功能。
    NOINIT  表明数据段可以初始化为零,只包含指示符。
    PIC   表明定位独立段,可以不修改情况下,在任意地址执行。
    READONLY  表明该段可读可写。

    注释:
    汇编时,必须至少有一个AREA指示符。使用AREA符号可以将源程序区分,但是必须不重名。通常需要独立的AOF段做为代码或者数据段,较大程序可以分为多个代码段。
    AOF段可以定义局部标签的范围,可以使用ROUT符号。
    如果没有任何的AREA指示符定义,汇编器将会产生名为|$$$$$$$|的AOF段和一条诊断信息,将限制由于缺少指示符而产生的错误信息,但是并不一定会成功汇编。
    例:
    AREA  Example,CODE,READONLY;一个例子的代码区
    ….     ;  代码
    2  CODE16
    功能:指示汇编器将随后的指令作为16位Thumb指令解释执行。

    格式:
    CODE16
    注释:
    使用BX指令转向Thumb状态时使用,为了将Thumb代码进行半字对准,必要时汇编器将插入1个字节。CODE16并不汇编成一条改变模式的指令。
    例:
    AREA   ThumbEx,CODE,READONLY
    ;ARM代码的开始。
    ADR   R0,start+1
    BX   R0   ;设置转移/交换指令
    CODE16   ;以下指令为Thumb指令
    Start   MOV   R1,#10   ;Thumb指令

    3  CODE32
    功能:指示汇编器将随后的指令作为32位ARM指令解释执行。

    格式:
    CODE32
    注释:
    在从Thumb状态转向时使用。为了将ARM代码进行字对准,必要时汇编器将插入3个字节。CODE32指示并不汇编成一条改变模式的指令。
    例:
    CODE16   ;Thumb指令的开始
    AREA     ThumbEx,CODE,READONLY
    MOV    R1,#10  ;Thumb指令
    ADR    R0,goarm
    BX      R0   ;设置转移/交换指令
    CODE32   ;以下为ARM指令
    Goarm     MOV   R4,#5     ;ARM指令

    4  END
    功能:表示源程序的结束。

    格式:
    END
    注释:
    所有汇编语言源文件必须以END结束。如果一个源文件在父文件中被GET指示符引用,汇编器将返回父文件,执行GET指示符下一语句。如果第一次汇编通过时在高层文件中遇到END,将开始第二汇编;如果汇编通过时在高层文件遇到END,将结束汇编。

    5  ENTRY
    功能:指向程序段开始点的AOF段的偏移量,一个源文件中只能有一个ENTRY。

    格式:
    ENTRY
    注释:
    在程序中必须定义惟一的ENTRY指示符,如果它不存在,或者有多个ENTRY,在链接时会产生错误信息。如果在单个文件有多个ENTRY存在,在汇编时将产生错误信息。
    例:
    AREA   ARMEx,CODE,RAEDONLY
          ENTRY
    6  ROUT
    功能:标记程序使用的范围的界限。

    格式:
    {name}  ROUT
    其中:
    name   界限的名称。

    注释:
    用ROUT限制局部标志的使用范围,从而避免使用了一个错误标志。如果没有ROUT,局部标志将代表整个AOF段。使用name选项,保证每个引用都正确。如果标志的名称或者引用与前ROUT指示符不一致,将会产生错误信息,汇编失败。
    例:
    routineaA   ROUT

    3rountine  ;
             ;
             BGE  %4rountineA
             ;
    4rountineA  ;
              ;
    otherstuff    ROUT

    7  #标志
    功能:描述“∧”符号,在“#”符号后定义的地址空间/

    格式:
    {Label}  #  expression
    其中:
    Label    可选的的标志,其定位计数器的值,然后定位计数器增加expression所代表的值。
    Expression  定位计数器所增加的字节数。

    注释:
    如果存储映射使用指定基础寄存器的“∧”符号,在“#”符号后定义的所有的标志将隐含使用该基址寄存器,直到下一个“∧”符号。
    例:
    ∧   0,r9    ;指向r9中的地址所指向的地址
    #     4       ;地址增量4
    Label  #    4  ;设置Label标志r9+4所指向的地址
    ;然后地址增加4
    LDR   R0,Label;同LDR  R0,[R9,#4]

    8  %标志
    功能:定义一块值为0的内存区域。

    格式:
    {Label}  %  numeric-expression
    其中:
    numeric-expression   值为0的字节数。
    注释:
    如果在Thumb状态下使用%定义带标志的数据,则必须使用DATA符号。如果要对%符号后的代码进行对准,必须使用ALIGN符号。
    例:
    AREA  MyData,DATA, READWRITE
    Datal  %   256   ;定义256字节的内存区域

    9  “∧”或MAP标志
    功能:标志一段地址的起始。

    格式:
    ∧expression{,base-register}
    其中:
    expression   数字或程序相关的表达式。
    如果没有指定基址寄存器,expression为存储映射开始的地址,存储定位计数器将指向该地址;
    如果expression为程序相关,在使用之前必须定义相应的标志。
    Base-register指定基址,运行时基址将寄存器中的值为存储映射开始地方。

    注释:在描述存储映射时,“∧”符号必须和“#”一起使用。
    可以指定基址寄存器定义程序相关的标志,在“#”标志后定义的所有标志都将隐含使用该基址寄存器,直到下一“∧”符号。
    “∧”符号可以在多重存储映射中使用多次。
    在第一个“∧”符号使用之前,@计数器设置为零。
    例:
    ∧   0,R3   ;指向R3中的地址所指向的地址
    ∧   0xff,R3  ;指向R3+0xff中的地址所指向的地址

    10  ALIGN标志
    功能:从1个字边界开始。

    格式:
    ALIGN  {expression  {,offset-expression} }
    其中:
    expression    2(上标为0)到2(上标为31)之间的任意数幂,当前按2(上标为n)字节对准,如果该参数没有指定,ALIGN将按字对准。
    Offset-expression  定义expression指定的对准方式的字节偏移量。
    注释:
    使用ALIGN符号,保证程序正确对准。对于Thumb地址,使用ALIGN符号保证其按字对准,例如:ADR  Thuub伪指令只能读取字对准的地址。
    在代码段出现数据定义符时,使用ALIGE符号。当在代码段使用数据定义符(DCB,DCW,DCWU,DCDU和%),程序计数器PC并不一定按字对准。汇编器会在下一条指令时插入3个字节,保证:
    ARM状态下按字对准;
    Thumb状态下按半字对准。
    在Thumb状态下,可以使用ALIGN2对Thumb代码按半字对准。
    使用ALIGN状态下,还可以充分利用一些ARM处理器的Cache,例如,ARM940T有一个每行4字的Cache,使用ALIGN16按16字节对准,从而最大限度使用Cache。
    例:
    AREA    Example,CODE,READONLY
    Start   LDR    R6,=Labell
    DCB     1   ;PC并不是指向一个字的开始
    ALIGN        ;确保Labell寻址到以下指令
    Labell
    MOV   R5,#0x5
    AREA   cacheable,COODE,ALIGH=4
    Routl…      ;从一个16字节边界开始

    MOV    pc,1r     ;从一个字边界开始
    ALIGH  16        ;从一个16字节边界开始
    Rout2 ….
    11  DATA
    功能:标志一个标签为代码段中数据的标签,该符号后为DCB或DCD。

    格式:
    Label    DATA
    其中:
    Label   数据定义符的标志,DATA符号必须和Label在同一行。

    注释:
    在Thumb代码中使用数据定义符如:DCD,DCB和DCW定义数据时,必须使用DATA符号。
    链接器重定位Thumb代码中的一个标志时,必须保证该标志指示一个Thumb段代码的入口地址,如果调用该段使用BX指令,链接器会将该标志的值加1。
    如果一个标志表示Thumb代码段数据的地址时,无须链接器将该标志加1。DATA符号将该标志表示为指向代码段数据的地址,链接器将其值增1。
    在ARM代码段中使用DATA符号标志数据,汇编器汇编时忽略DATA符号。
    例:
    AREA    example,CODE
    Thumb_fn   ;
              ;
              MOV     pc,1r
    Thumb_Data  DATA
               DCB      1,3,4

    12  DCB或“=”
    功能:分配一个或多个字节

    格式:
    {label}DCB  expression{,expression}…
    其中:
    expression    可以是:
    整数表达式,取值范围在—128到255之间。

    注释:
    如果在Thumb代码中,使用DCB符号定义带标志的数据时必须使用DATA符号。
    如果DCB符号是一条指令,必须使用ALIGN符号保证该指令正确对准。
    例:
    C_string   DCB   “C_string”,0


    13  DCD或“&”
    功能: 分配一个或多个字,从4个字节边界开始。

    格式:
    {label}DCD  expression{,expression}…
    其中:
    expression    可以是:
    一个数学表达式;
    一个程序相关的表达式。

    注释:
    如果在Thumb代码中,使用DCD符号定义带标志的数据时则必须使用DATA符号。
    按4个字节对准时,DCD符号会在第一个字节之前插入3个字节的空字符,如果无须对准的话,可以使用DCDU符号。
    例:
    datal   DCD    1,5,20
    data2   DCD    mem06
    data3    DCD  glb+4

    14  DCW
    功能:分配给一个或多个半字以半字边界开始的内存区域。

    格式:
    {label}DCW  expression{,expression}…
    其中:
    expression    可以是等于—32768到65536之间的整数数字表达式。
    注释:
    如果在Thumb代码中,使用DCW符号定义带标志的数据时则必须使用DATA符号。对于DCW符号后的指令,使用ALIGNA符号保证指令正确字对准。
    按两字节对准时,DCW符号会在第一个字之前插入1个字节的空位符,如果无须对准的话,可以使用DCWU符号。
    例:
    AREA   MiscData,DATA,READWRITE
    Datal    DCW   —255,2*number
           DCW    number

    15  LTORG
    功能:标志汇编译生成的常量,这是一个文字池(literal pool)。

    格式:
    LTORG

    注释:
    与AREA符号在开头定义一样,LTORG应放在代码结束处,否则汇编器将在汇编结束时生成文字池。
    使用LTORG符号保证符号库编译时在LDR,LDFD和LDFS伪指令的寻址范围。
    在无条件转移和子程序返回指令后插入LTORG符号,使处理器不能把常量当作指令执行。
    例:
    AREA    Example,CODE,READONLY
    Start   BL   funcl
    Funcl  

    LDR    R1,=0X55555555;同LDR  R1,[pc,#offset  to  literal  pool1]

    MOV   pc,1r
    LTORG;literal  pool  1包含&55555555
    Data  %   4200
    END

    16  CN指令
    功能:定义一个协处理器寄存器名。

    格式:
    name  CN  numeric—expression
    其中:
    name    定义的协处理器名
    numeric—expression     协处理器号,0到15

    注释:
    使用CN对协处理器寄存器分配合适的名称,以便记忆。C0~C15已经预定义了。
    例:
    power  CN   6    ;定义power作为协处理器寄存器6的标志

    17  CP指令
    功能:定义一个特定协处理器寄存器名,协处理器号从0到15。

    格式:
    name   CP   numberic--expression
    其中:
    name      定义的协处理器名。注意不要与预定义的名相同。
    Numberic—expression  协处理器号,0~15。

    注释:
    使用CP符号对协处理器分配合适的名称,以便记忆。P0~p15已经预定义了。
    例:
    dmu   CP   6  ;定义dmu作为协处理器6的标志

    18  EQU或“*”
    功能:对一个数字常量赋予一个符号名。

    格式:
    name    EQU   expression
    其中:
    name   符号名。
    Expression    寄存器相关或者程序相关的固定值。

    注释:
    使用EQU定义常量,与C语言中用#define定义一个常量。
    例:
    num   EQU   2    ;   数字2赋予符号num

    19  EXPORT或GLOBAL
    功能:标识链接对独立对像和库文件解析符号。

    格式:
    EXPORT   symbol   {[qualifier {,qualifier} {,qualifire}]}
    其中:
    symbol    引入的符号名,对大小写敏感。
    Qualifier   可以是以下参数之一:
    FPREGARGS    与传递浮点参数的函数有关;
    DATA   与数据定位有关,而不是函数和程序入口
    LEAF   指明输入函数为无须调入其他的函数,该参数已过时。

    注释:
    使用EXPORT符号可以在其他文件中引入当前的文件符号。
    使用DATA属性告知链接器该符号不在目标转移中。
    例:
    AREA    Example,CODE,READONLY
    EXPORT   DoAdd  ;输出被外部模块使用的函数名
    DoAdd     ADD   R0,R0,R1

    20  FN
    功能:定义一个特定的浮点寄存器名。

    格式:
    name    FN   numeric--expression
    其中:
    name     定义的浮点寄存器名。注意不要与预定义的名称相同。
    Numeric—expression  浮点寄存器号,0~7。
    注释:
    使用FN对浮点寄存器分配合适的名称,以便记忆。
    例:
    energy    FN  6   ;定义energy作为浮点寄存器的6的标志


    21  RN
    功能:定义特定的寄存器名。

    格式:
    name  RN   numeric--expression
    其中:
    name     定义的寄存器名,注意不要与预定义名相同。
    numeric—expression   寄存器号,0~15

    注释:
    使用RN符号对寄存器分配合适的名称,以便记忆。
    例:
    regname    RN   R11   ;定义寄存器11为regname
    sqR4       RN   R6    ;定义寄存器6为sqR4

    22  IF-ELSE-ENDIF
    功能:设置汇编指令的次序。

    格式:
    IF   logical—expression

    {ELSE
    …}
    ENDIF
    其中:
    logical—expression  等于{TRUE}或{FALSE}的表达式。
    注释:
    使用IF,ELSE,和ENDIF符号可以使指令按指定次序执行。IF。。。ENDIF可以嵌套使用。
    例:
    [Version=“1.0”    ;如果…
                      ;
    |                   ; 或者

    ]                        ;结束


    23  “|”或ELSE标志
    功能:与上述指示符第(22),(23)项的符号连用。

    格式:
    ELSE

    24  ENDIF标志
    功能:与上述指示符第(22),(23)项的符号连用。

    格式:
    ENDIF

    25  GET或INCLUDE
    功能:引进一个被编译过的文件。

    格式:
    GET    filename
    其中:
    fiename    汇编时引入的文件名,可以有UNIX和MS—DOS下的路径名。
    注释:
    GET符号在汇编时对宏定义,EQU符号以及存储映射时是很有用的,在引入文件汇编完以后,汇编将从GET符号后开始.
    在缺省状态下,汇编器将在调用文件所在的目录查找引入文件,使用汇编器下的“--i”命令行参数,将添加查找路径的目录。
    在被引入的文件中可能有GET符号再引入其他的文件。
    GET符号不能用来引入目标文件。
    例:
    AREA    Example,CODE,READONLY
    CET      filel,s     ;如果文件filel存在,则引进
    ;
    GET     C:\project\file2.s    ;如果文件filei存在,则引进


    26  INCBIN
    功能:引进一个未被编译过的文件。

    格式:
    INCBIN    filename
    其中:
    filename    汇编时引入的文件名,可以有UNIX和MS—DOS下的路径名。
    注释:
    使用INCBIN符号可以引入可执行文件和数据。文件的内容可以按字节添加进当前的AOF段中,汇编将从INCBIN符号后开始。
    在缺省状态下,汇编器将在调用文件所在的目录查找引入文件,使用汇编器下的“--i”命令行参数,将添加查找路径的目录。
    例:
    AREA   Example,    CODE,READONLY
    INCBIN   filel,dat      ;如果filel文件存在,则引进

    INCBIN   c:\project\file2.txt;   如果file2文件存在,则引进

    27  MACRO。。。MEND
    功能:标志一下宏的定义。

    格式:
    MACRO
    Macro_prototype

    MEND
    MACRO符号必须在宏表达式之后一行,宏表达式的格式如下,
    {$label}   macroname    {$ parameter{,parameter2}…}
    其中:
    $ label   参数,在宏使用时,被给定的符号替代。
    Macroname   宏的名称,并不一定以一条指令或者符号名开始。
    $parameter    在宏使用时,被替代的参数,格式为:
         $  parameter=“default value”
    注释:
    MACRO和MEND之间必须没有WHILE…WEND或者IF。。。ENDIF符号。
    在宏体中,参数如:$parameter和变量一样使用,在被宏引用时,被赋于新值,参数必须用“$”符号加于区别。$label在宏定义内部符号时很有用,可以看作宏的参数。
    使用“|”符号作为使用一个参数缺省值的变量,如果使用的是一个空格符串,将省去该变量。
    在使用内部标志的宏定义中,将内部标志定义为带后缀的标志,将会很有用。
    如果在扩展中空间不够,可以作为参数和后继文字之间或者参数之间使用圆点隔开,但在文本和后继参数之间不能使用圆点。
    宏可以定义局部变量的范围。
    宏可以嵌套使用。
    例:
    MACRO        ;宏定义的开始
    $label    xmac    $p1,$p2
                    LCLS   err
    $labell,loopl
             BGE    $pl
    $labell,loop2
            BL     $p1
           BEG      $p1
           BEG      $labell,loop2
           ;
    MEND             ; 宏定义结束
    Abc    xam    subR1,de        ;调用宏
    Abcloopl   ;
             ;
             BGT     subR1
             ;
             ADR      de

    28  MEXIT
    功能:用来在结束前终止宏定义。

    格式:
    MEXIT

    注释:
    使用MEXIT符号结束宏体的使用,在宏体结束之前汇编器会强制结束WHILE…WEND或者IF…ENDIF符号。
    例:
    MEACRO
    $abc        macroabc
               WHILE  condition

    IF      conditionl2

    MEXIT
    ELSE

    ENDIF
    ;code
    MEND

    29  WHILE…WEND
    功能:确定重复编译的指令次序。

    格式:
    WHILE   logical—expression
             Code
             WEND
    其中:
    logical—expression    等于{TRUE}或者{TRUE}的表达式。

    注释:
    使用WHILE和WEND符号可对指令重复执行。在WHILE…WEND之间可以使用IF…ENDIF符号。
    WHILF和WEND符号可以嵌套使用。
    例:
    count    SETA    1
            WHILE   count<=4     ;代码循环执行4遍
    Count    SETA    count+1
            …
            WEND

     


    © 中文版权所有: 南开大学嵌入式系统与信息安全实验室
    程序版权所有: 雷傲科技  版本: LeoBBS X Build040926
     

    本论坛言论纯属发表者个人意见,与 南开大学嵌入式系统与信息安全实验室学术论坛 立场无关
    当前页面执行消耗时间: 1171.00 毫秒 [Gzip: On, Level: 9]