ARM指令详解2

来源:互联网 发布:电脑数据库在哪里打开 编辑:程序博客网 时间:2024/05/20 13:19

首先详细介绍ARM指令集,ARM指令集包括标准ARM指令集和Thumb指令集,并介绍ARM的宏汇编以及ARM汇编语言编程。


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

原创粉丝点击