ARM汇编:
指令
伪指令
符号
arm指令分类:
跳转指令
数据处理指令
数据传送指令
乘法指令
Load/Store(加载存储)指令
程序状态寄存器访问指令
通用寄存器和存储器内容交换指令
异常产生指令
协处理指令(暂时不讲)
信号量指令(暂时不讲)
其他扩展指令(暂时不讲)
指令寻址方式:
数据处理指令操作数寻址方式
内存访问指令寻址方式
几乎所有arm指令都能条件执行:
31 30 29 28 四位表示条件位,共16个条件。
Cpsr中的条件标志位NZCV的值来确定指令是否执行。
cond的16种条件:
shifter_operand(第二源操作数)的三种形式:
# 立即数
指令里面的立即数前面加#。
嵌入式一般用十六进制,前面加0x。
寄存器
寄存器移位9种:
逻辑左移:将Rm寄存器逻辑左移shift_imm(立即数)位或Rs(寄存器)位。
,LSL #/
逻辑右移:
,LSR #/
算术右移:
,ASR #/
循环右移
,ROR #/
扩展循环右移:
,RRX :Rm扩展的循环右移一位。
S标志位:
决定是否更新cpsr中的标志位;
如果S=1,更新cpsr标志位,当Rd不为R15,cpsr中的NZCV根据指令的执行结果设置,其他位不动;当Rd是R15,当前程序状态的spsr拷贝到cpsr。
如果S=0,不更新cpsr。
{}表示可选项.
-----------------------------------------
跳转指令:
B :跳转,用于死循环
BL :带返回的跳转,函数调用
BX :跳转并切换状态
BLX:带返回的跳转并切换状态
三种跳转形式:
1.跳转到标号处LABLE
2.跳转到绝对地址0xXXX
3.跳转到子程序func处
-----------
跳转(B)和带返回的跳转(BL)
B{L}{}
编码格式:
条件代码标识 控制位
31-28 24 23-0
NZCV 101 L 跳转的地址
L:L位,也就是寄存器的24位,bit【24】=1,指令存储返回地址到LR,bit【24】=0,不保存返回地址。
cond:指令执行的条件
target_address:指令跳转的目标地址;计算目标地址方法:
将24位带符号的补码立即数扩展为32位;
将扩展后的32位立即数左移两位;
将得到的值加到PC寄存器中即可。
----------
跳转并切换状态
BX{}
Rm的第0位拷贝到cpsr的T位,其他位移入PC。
编码格式:
条件代码标识
31-28 19-16 15-12 3-0
NZCV 00010010 SB0 SB0 0001 Rm
cond:指令执行条件
:包含跳转指令的目标地址;Rm的bit【0】=0,目标地址处指令为ARM指令;如果bit【1】=1,目标地址处指令为Thumb指令。
----------
带状态切换的连接跳转指令
BLX
编码格式:
条件代码标识
31-28 24 23-0
1111 101 H Rm
target_add:指令的跳转目标地址;计算方法:
将24位扩展为32位立即数;
将结果左移两位;
将H(bit【24】)加到结果地址的第一位bit【1】;
将结果累加进程序计数器pc中。
BLX{comd}
Rm的第0位拷贝到cpsr的T位,其他位移入PC。
编码格式:
条件代码标识
31-28 19-16 11-8 3-0
NZCV 00010010 SB0 SB0 0011 Rm
cond:指令执行条件
Rm:寄存器Rm指定转移目标,Rm的bit【0】=1,跳转时自动将cpsr的标志位T置位,就是解释为Thumb,否则解释为ARM。
-------------------------------------------
数据处理指令:
算数运算指令
ADD:加
ADC:带进位的加
SUB:减
RSB:翻转减
SBC:带进位的减
RSC:带进位的翻转减
测试与测试指令
TST:测试
TEQ:测试相等
CMP:比较
CMN:负数比较
逻辑指令
BIC:位清0
AND:逻辑加
ORR:逻辑或
EOR:逻辑异或
编码格式:
条件代码标识
31-28 25 24-21 20 19-16 15-12 11-0
NZCV 00 I opcode S Rn Rd shiter_operand
I:区分第二操作偶数是立即数还是寄存器
S:标志指令的条件域是否更新cpsr
Opcode:操作符
Rd:指示目的寄存器
Rn:指示第一源操作寄存器
Shifter_operand:指示第二源操作数,可以是立即数,寄存器,寄存器移位三种形式:
数据处理指令的语法格式分两种:
算术运算和逻辑运算的格式:
{}{S} ,,
比较和测试的格式(没有Rd; S=1)
{} ,
-----
算数运算指令
ADD{}{S} ,,
将shifter_operand加Rn,结果存到Rd中。
ADC{}{S} ,, 带进位的加法,处理大于32位的加法
将shifter_operand加Rn,再加cpsr中的C标志位,结果存到Rd。
SUB{}{S} ,,
将Rn减shifter_operand,结果保存到Rd中。
SBC{}{S} ,, 带进位的减法,处理大于32位的减法
Rn减去shifter_operand,再减去cpsr中的C标志位的反码,结果保存到Rd。
RSB{}{S} ,, 翻转减,处理负数
shifter_operand减去Rn,结果保存到Rd。
RSC{}{S} ,, 带进位的翻转减,处理大于32位的负数
shifter_operand减去Rn,再减去cpsr中的C标志位的反码,结果保存到Rd。
-----
逻辑运算指令
AND{}{S} ,, 逻辑与
Rn与shifter_operand按位逻辑与,结果保存到Rd中。
与1与会保持不变,与0与变为复位(变0)。
EOR{}{S} ,, 逻辑异或,不同则为1,相同则为0
Rn和shifter_operand进行按位逻辑异或,结果保存到Rd中。
与0异或保持不变,与1异或会反转。
ORR{}{S} ,, 逻辑或
Rn与shifter-_operand进行按位逻辑或,结果保存到Rd中。
与0或会保持不变 ,与1或可以置位(変1)。
BIC{}{S} ,,
Rn的源码与shifter_operand的反码按位进行逻辑与,结果保存到Rd中。
-----
比较测试
CMP{} , 比较指令
用Rn减去shifter_operand,自动更新cpsr的标志位。
CMN{} , 负数比较指令
用Rn的原值减去shifter_operand的负数指(相当与两者相加),自动更新cpsr的标志位。
TST{} , 测试指令
将Rn和shifter_oerand进行按位逻辑与,自动更新cpsr的标志位。
TEQ{} , 测试相等指令
将Rn和shifter_operand进行按位逻辑异或,自动更新cpsr的标志位。
---------------------------------------------
数据传送指令:
MOV{cond}{S} ,
编码格式:
条件代码标识
31-28 20 15-12 11-0
NZCV 00 1 1101 S 0000 Rd shiter_operand
cond:条件,指令只有在条件满足时才执行。
S:S标识,S(bit【20】)=1,更新cpsr。如果Rd=r15,CPSR=SPSR,如果Rd不是r15,根据传送的数值设置cpsr的NZCV。如果S=0,不更新cpsr。
Rd:确定目标寄存器
shifter_operand:确定操作数,可以是立即数,寄存器,寄存器移位的形式。
MVN{}{S} ,
传送反码,将shifter_operand按位取反传送给Rd。
编码格式:
条件代码标识
31-28 20 15-12 11-0
NZCV 00 1 1111 S 0000 Rd shiter_operand
-------------------------------------------
乘法指令
编码格式:
31-28 23-21 20 19-16 15-12 11-8 3-0
NZCV 0000 mul S Rd/RdHi Rn/RdLo Rs 1001 Rm
mul:
RdHi:RdLo 由RdHi(最高有效32位)和RdLo(最低有效32位)链接形成的64位数
[31:0] 表示只选取结果的最低有效32位。
:= 表示简单的赋值。
S:S位,控制cpsr条件控制位的设置,具体设置如下:
产生32位结果,N=Rd【31】;64位结果的,N=RdHi【31】。
产生32位结果,Rd=0时,Z=1;64位结果的,RdHi和RdLo都为0,Z=1.
C设置成无意义的指,V不变。
MUL{}{S} ,, 乘法指令
31-28 23-21 20 19-16 11-8 3-0
NZCV 0000 000 S Rd Rs 1001 Rm
Rm*Rs,取结果的最低32位保存到Rd中。
MLA{}{S} ,,, 乘-累加指令
31-28 23-21 20 19-16 15-12 11-8 3-0
NZCV 0000 001 S Rd Rn Rs 1001 Rm
Rm*Rs,乘积加Rn,取结果的低32位保存到Rd。
UMULL{}{S} ,,, 无符号长乘指令
31-28 23-21 20 19-16 15-12 11-8 3-0
NZCV 0000 100 S RdHi RdLo Rs 1001 Rm
Rm和Rs进行无符号相乘,结果低32位保存到RdLo,高32位保存到RdHi。
UMLAL{}{S} ,,, 无符号长乘-累加指令
31-28 23-21 20 19-16 15-12 11-8 3-0
NZCV 0000 101 S RdHi RdLo Rs 1001 Rm
Rm和Rs做无符号相乘,64位乘积与RdHi:RdLo相加,结果低32位保存到RdLo中,高32位保存到RdHi中。
SMULL{}{S} ,,, 有符号数长乘指令
31-28 23-21 20 19-16 15-12 11-8 3-0
NZCV 0000 110 S RdHi RdLo Rs 1001 Rm
Rm和Rs做有符号相乘,结果低32位保存到RdLo中,高32位保存到RdHi中。
SMLAL{}{S} ,,, 有符号数长乘-累加指令
31-28 23-21 20 19-16 15-12 11-8 3-0
NZCV 0000 111 S RdHi RdLo Rs 1001 Rm
Rm和Rs做有符号相乘,64位乘积和RdHi:RdLo相加,结果低32位保存到RdLo中,高32位保存到RdHi中。
-------------------------------------------
ARM加载存储指令
单寄存器加载/存储指令:单数据传送,字节,半字和字都可以。
多寄存器加载/存储指令:传大数据,进程进入、退出、保存、恢复,内存数据拷贝。
单寄存器交换指令:寄存器和存储器进行数据交换,用于多处理器实现信号量。
-----
单寄存器指令:
字:
LDR:Load 加载:从内存到寄存器
STR:Store 储存:从寄存器到内存
B:字节
H:半字
S:有符号
T:用户模式
31-28 25 24 23 22 21 20 19-16 15-12 11-0
NZCV 0 X L P U I W S Rn Rd addr_mode
L:L=1,进行加载,否则是存储
P:P=1,使用预先变址寻址,否则使用过后变址寻址
U:U=1,给出的偏移量被加到基址寄存器上,否则从中减去偏移量
W:预先变址寻址,W=1,强制用作地址转换的最终地址写回基址寄存器;
过后变址寻址,W=1,在进行传送之前强制进行地址转换。
LDR{} , 字数据加载指令
31-28 25 24 23 21 19-16 15-12 11-0
NZCV 01 L P U 0 W 1 Rn Rd addr_mode
从内存中将一个32位字读取到目标寄存器Rd。
STR{} , 字数据存储指令
31-28 25 24 23 21 19-16 15-12 11-0
NZCV 01 L P U 0 W 0 Rn Rd addr_mode
将寄存器Rd中一个32位的字数据写入到一个内存单元。
LDRB{}B , 字节数据加载指令
31-28 25 24 23 21 19-16 15-12 11-0
NZCV 01 L P U 1 W 1 Rn Rd addr_mode
将一个8位字节读取到目标寄存器Rd。
STRB{}B , 字节数据存储指令
31-28 25 24 23 21 19-16 15-12 11-0
NZCV 01 L P U 1 W 0 Rn Rd addr_mode
从寄存器Rd中取出8位字节放入内存单元低8位,高位补0.
LDRH{}H , 半字数据加载指令
31-28 24 23 21 19-16 15-12 11-8 4-0
NZCV 010 P U 1 W 1 Rn Rd addr_mode 1011 addr_mode
从内存将一个16位的半字读取到目标寄存器Rd。
STRH{}H , 半字数据存储指令
31-28 24 23 21 19-16 15-12 11-8 4-0
NZCV 000 P U 1 W 0 Rn Rd addr_mode 1011 addr_mode
从寄存器取出指定的16位半字放入指令中指定的内存单元的低16位,将高位补0.
LDR{}T , 用户模式字加载指令
31-28 25 23 19-16 15-12 11-0
NZCV 01 L 0 U 1 1 1 Rn Rd addr_mode
从内存中将一个32位的字读取到目标寄存器Rd。
post_indexed_addressing_mode:使用后索引地址模式寻址。
STR{}T , 用户模式字存储指令
31-28 25 23 19-16 15-12 11-0
NZCV 01 L 0 U 0 1 0 Rn Rd addr_mode
将寄存器Rd中的一个32位的字写入到内存中。
post_indexed_addressing_mode:使用后索引地址模式寻址。
LDR{}BT , 用户模式字节加载指令
31-28 25 23 19-16 15-12 11-0
NZCV 01 L 0 U 1 1 1 Rn Rd addr_mode
从内存读取一个8位字节到目标寄存器Rd。
post_indexed_addressing_mode:使用后索引地址模式寻址。
STR{}BT ,,
用户模式字节存储指令
31-28 25 23 19-16 15-12 11-0
NZCV 01 L 0 U 1 1 0 Rn Rd addr_mode
将寄存器Rd中的一个8位的字节写入到内存中。
post_indexed_addressing_mode:使用后索引地址模式寻址。
LDR{}SB , 有符号字节传送指令
31-28 24 23 22 21 19-16 15-12 11-0
NZCV 000 P U I W 1 Rn Rd addr_mode
将一个8位的字节读取到目标寄存器Rd。
LDR{}SH , 有符号半字传送指令
31-28 24 23 22 21 19-16 15-12 11-8 11-0
NZCV 000 P U I W 1 Rn Rd 1111 addr_mode
将一个16位的半字节读取到目标寄存器Rd。
-----
多寄存器加载存储指令
主要用途现场保护,数据复制,参数传递,有8中模式(address_mode):
数据块传输:
IA:每次传送后地址加4
IB:每次传送前地址加4
DA:每次传送后地址减4
DB:每次传送前地址减4
堆栈操作:
FD:满递减堆栈
ED:空递减堆栈
FA:满递增堆栈
EA:空递增堆栈
多寄存器内存字数据传送指令:
LDM{} {!},
31-28 24 23 21 19-16 15-0
NZCV 100 P U 0 W 1 Rn register_list
将数据从连续的内存单元中读取到寄存器列表中。
address_mode:指令的寻址方式,确定PUW位
Rn:基址寄存器
!:设置W位
registers:被加载的寄存器列表
STM{} {!},
31-28 24 23 21 19-16 15-0
NZCV 100 P U 0 W 0 Rn register_list
将寄存器列表中各寄存器数据写入到连续的内存单元中。
address_mode:指令的寻址方式,确定PUW位
Rn:基址寄存器
!:设置W位
registers:被加载的寄存器列表
用户模式多寄存器内存字数据传送指令:
LDM{} ,
31-28 24 23 21 19-16 15-0
NZCV 100 P U 1 W 1 Rn register_list
将数据从连续的内存单元读取到指令中指定的寄存器列表中的各寄存器。
STM{} ,
31-28 24 23 21 19-16 15-0
NZCV 100 P U 0 W 0 Rn register_list
将寄存器列表中的各寄存器数值写入到内存单元。
带状态寄存器的多寄存器字数据装载指令:
LDM{} {!},
31-28 24 23 21 19-16 15-0
NZCV 100 P U 1 W 1 Rn register_list
将数据从连续的内存单元读取到寄存器列表。
-----
通用寄存器和存储器内容交换指令
用于进程同步
SWP{} ,,[]
31-28 19-16 15-12 11-8 3-0
NZCV 00010000 Rn Rd SBZ 1001 Rm
Rn:内存单元地址寄存器
Rd:确定指令的目标寄存器
Rm:包含将要被存储到内存单元中的数据的寄存器
将一个内存单元【Rn】中的字数据读取到寄存器Rd中,同时将寄存器Rm的字数据写入到内存单元【Rn】中。
SWP{}B ,,[]
31-28 19-16 15-12 11-8 3-0
NZCV 00010100 Rn Rd SBZ 1001 Rm
Rn:内存单元地址寄存器
Rd:确定指令的目标寄存器
Rm:包含将要被存储到内存单元中的数据的寄存器
将一个内存单元【Rn】中的字节数据读取到寄存器Rd中,同时将寄存器Rm的字节写入到内存单元【Rn】中。
------------------------------------------------
程序状态寄存器访问指令:
ARM提供两条指令,直接控制程序状态寄存器psr。
将程序状态寄存器的值送到通用寄存器
MRS{} ,CPSR/SPSR
31-28 22 19-16 15-12 12-11
NZCV 00010 R 00 SB0 Rd SBZ
R:如果R=1,Rd=SPSR;R=0,Rd=CPSR
将通用状态寄存器的值送到程序状态寄存器
MSR{} CPSR_/SPSR_,
31-28 22 19-16 15-12 8-11 3-0
N ZCV 00010 R 10 FSXC SB0 SBZ 0000 Rm
R:如果R=1,SPSR=Rd;R=0,CPSR =Rd
将立即数送给程序状态寄存器
MSR{} CPSR_/SPSR_, #
31-28 22 19-16 15-12 11-8 7-0
N ZCV 00110 R 10 FSXC SB0 8_bit_immediate
R:如果R=1,SPSR=immediate;R=0,CPSR=immediate
域标志位field:
F:标志位掩码域
S:状态位掩码域
X:扩展位掩码域
C:控制位掩码域
------------------------------------------------
异常产生指令
SWI{}
31-28 23-0
N ZCV 1111 immed_24
immed_24:24位立即数。
SWI用于产生软中断,实现从用户模式变换到管理模式,cpsr保存到管理模式的spsr,执行转移到SWI向量。
---------------------------------------------------------------------
Arm伪指令:
ADR:装载程序相关或寄存器相关地址(小范围)到寄存器。
ADRL:装载程序相关或寄存器相关地址(中等范围)到寄存器。
MOV32:装载32位常数或地址到寄存器。
LDR:装载32位常数或地址到寄存器。
NOP:执行一条空操作,用于延时。
ADR{cond}{.W} register,lable
Cond:指令执行条件
.W:指定指令宽度
Register:目标寄存器
Label:基于PC或具体寄存器的表达式
ADRL{cond} register,label
Cond:指令执行条件
Register:目标寄存器
Label:基于PC或具体寄存器的表达式
LDR{cond}{.W} register,=[expr|label-expr]
Cond:执行条件
.W:指令宽度
Register:目标寄存器
Expr:32位常量表达式
Label-expr:一个程序相关或声明为外部的表达式。
NOP
可以用mov ro,ro替换
-------------------------------------------------------------------------------------------------------------------
arm处理器寻址方式有9种:
1.寄存器寻址(寄存器Rn中存放的数就是操作数)
2.立即数寻址(立即数#0xXXXXXXXX作为操作数)
3.寄存器移位寻址(寄存器中存放的值进行移位操作之后作为操作数)
4.寄存器间接寻址([Rn],将Rn寄存器中存放的值作为操作数的地址)
5.基址寻址([Rn,#0xXXX],将Rn寄存器中存放的值加上立即数作为操作数的地址)
6.多寄存器寻址({Rn-Rm,Rk},在大括号中可以放多个寄存器,进行批量操作)
7.堆栈寻址
8.块拷贝
9.相对寻址
寄存器移位方式有9种:
ASR #n/:算术右移
LSL #n/:逻辑左移
LSR #n/:逻辑右移
ROR #n/:循环右移
RRX:带扩展的循环右移一位
#n表示立即数,表示偏移量寄存器。
arm指令分类:
数据处理指令(算数运算、位运算、比较测试、数据传送)
乘法指令
跳转指令
加载存储指令(load/store)
寄存器访问指令(程序状态寄存器、通用寄存器)
异常中断指令
协处理指令
信号量指令
伪指令(arm伪指令,thumb伪指令、符号定义伪指令、数据定义伪指令、报告伪指令、汇编控制伪指令、其他伪指令)
arm指令格式:
{}{S} ,{, operand2}
<>:表示必须
{}:表示可选
opcode:指令助记符
Rd:目标寄存器
Rn:源寄存器(第一操作数寄存器)
operand2:第二操作数(可以是立即数、寄存器、寄存器移位)
cond为指令执行条件
寄存器的高四位为条件cond:
31
30
29
28
N
Z
C
V
N:=1,负数
Z:=1,零
C:=1,进位
V:=1,溢出
条件码助记符有16种:
31-28
助记符
说明
检测条件
0000
EQ
相等 /等于零
Z=1
0001
NE
不等
Z=0
0010
CS/HS
进位 /无符号数大于或等于
C=1
0011
CC/LO
无进位 /无符号数小于
C=0
0100
MI
负数
N=1
0101
PL
正数 /零
N=0
0110
VS
溢出
V=1
0111
VC
未溢出
V=0
1000
HI
无符号数大于
C=1&Z=0
1001
LS
无符号数小于或等于
C=0&Z=1
1010
GE
有符号数大于或等于
N=V
1011
LT
有符号数小于
N !=V
1100
GT
有符号数大于
Z=0 & N=V
1101
LE
有符号数小于或等于
Z=1 | N !=V
1110
AL
总执行
任何状态
1111
NV
从不执行
无
指令限制:
指令都是32位的等宽,造成了分配出来存放立即数的位数不同,所以带立即数的数据处理指令受到限制。
数据处理指令(16种)
条件位
指令助记符
CSPR
源寄存器
目标寄存器
第二操作数
31—28
27
26
25
24
23
22
21
20
19——16
15——12
11——0
NZCV
0
0
I
S
Rn
Rd
立即数
跳转指令B、带连接的跳转指令BL
条件位
24位跳转地址
31—28
27
26
25
24
23——0
N Z C V
1
0
1
L
立即数
带状态切换的链接跳转指令BLX
条件位
24位跳转地址
31—28
27
26
25
24
23——0
N Z C V
1
0
1
H
立即数
软中断指令SWI
条件位
24位操作数
31—28
27
26
25
24
23——0
N Z C V
1
1
1
1
立即数
第二操作数是立即数时:
必须是一个8位的常数经过偶数位循环移位得到。
arm伪指令:
ADR:将基于PC的相对偏移地址的值读取到寄存器中。
ADR{} Rd,addr_expr
ADRL:将基于PC相对偏移地址的值,或基于寄存器相对偏移地址的值读取到寄存器中。
ADRL{} Rd,addr_expr
LDR:加载32位立即数或一个地址到指定寄存器。
LDR{} Rd,addr_expr/#n
注意:LDR既可以作为arm伪指令,也可以作为加载指令。
NOP:空操作伪指令,用于延时。
NOP
通用伪指令
以下伪指令为编译器定义,所以可以通用,都是以.开头。
.equ symbol, expr
.set 同.equ
Symbol:要指定的名称
Expr:常量或
相当于宏定义,用symbol来代替expr。
.global symbol
.globl同.global
Symbol:要声明的全局符号
在一个文件中声明一个全局变量或全局函数,在别的文件能够访问
.extern symbol
Symbol:要声明的外部标号
.ltorg
.pool
声明一个数据缓冲池的开始。
.byte expr{, expr}…
Expr:数字表达式或程序中的标号。
定义一个字节,相当于定义一个char类型
.hword expr{, expr}…
.short expr{, expr}…
Expr:数字表达式或程序中的标号
定义一个半字,两个字节,相当于short int。
.word expr{, expr}…
.int expr{, expr}…
.long expr{, expr}…
Expr:数字表达式或程序中的标号
定义一个字,四个字节,相当于int,long int(32位)
.ascii expr{, expr}…
.asciz expr{, expr}…
.string expr{, expr}…
Expr:表示字符串
定义一个字符串,相当于char *
.quad expr{, expr}…
Expr:数字表达式
定义双字,相当于八个字节,long int(64位)
.zero
分配number_of_bytes字节的数据空间,用0填充内存
.space {, }
.skip同.space
分配number_of_bytes字节数据空间,用fill_byte填充,缺省用0.
.fill repeat{, size}{, value}
Repeat:重复填充的次数
Size:每次填充的字节,默认为1
Value:所填充的数据,默认为0
定义重复内存单元
.double expr{. Expr}…
Expr:为32位的单精度浮点数
定义一个双精度浮点数
.arm
.code32
表示是arm指令,32位指令
.thumb
.16
表示thumb指令,16位指令
.section {, “”}
Section_name:段名称,可以自定义,也可以使用预定义的(test,data,bss)。
Flags:elf文件格式的标志,a(可加载段,可读),w(可写段),x(可执行段)。
定义一个段
.text
代码段
.data
数据段
.bss
Bss段
.end
表示源文件的结束,如果之后还有代码不会被编译执行
.include “filename“
将指定的文件filename在使用的位置展开(一般是头文件)
.incbin “file”[, skip[, count]]
File:一个二进制文件
Skip:从文件开头跳过skip个字节
Count:读取的字数
将一个原封不动的二进制文件编译到当前文件中。
.align [ab***pr1, ab***pr2]
Ab***pr1:表示对齐方式,(4,8,16,32等)
Ab***pr2:表示填充的值
指定数据对其方式,以ab***pr1方式对齐,在未使用的区域用ab***pr2填充。
.balign和.align相同
.if
.else
根据表达式的值决定下面的代码是否编译,endif表示结束条件判断。
.ifdef
.else
.endif
条件编译伪操作,满足条件就编译。
.macro 宏名 参数列表
宏体
.exitm或.endm @表示宏结束
.rept 重复次数
数据定义
.endr @结束重复定义
用来重复定义一个或几个数据
ARM汇编程序设计的格式
[:] [] @comment
Label:标号
Instruction:汇编指令
Pseudo-instruction:伪指令
Directive:伪操作
@:注释
C和汇编混合编程
只有C和汇编都遵循标准,才能相互调用,ATPCS就是一个公共标准。
C和汇编混合引用的内容:
函数;
变量。
C和汇编混合引用的方式:
C内嵌汇编;
C和汇编相互引用。
ATPCS(arm/thumb程序调用标准):
规定寄存器的使用;
规定函数传参方式;
规定栈使用方法。
1. 寄存器的使用
未备份寄存器:
R0-R3:作为函数传递的参数值,想用就用,可记作A1-A3;
备份寄存器:
R4-R11:arm状态下保存局部变量,寄存器变量必须保护,可记作V1-V8;
使用之前要先保存,使用之后要恢复(压栈出栈)。
有临时第二功能:
R12:函数调用时用来临时保堆栈指针,函数返回时进行出栈,记作IP
第二功能寄存器:
R13-R15:有第二功能的寄存器,以第二功能为主。
2.函数传参方式:
参数个数可变的子程序参数调用规则:
如果参数个数不超过四个,用R0-R3来传递;
如果参数个数超过四个,多出的参数使用栈来传递参数。
参数个数固定的子程序参数传递规则:
如果系统不包含double(64位)类型,如果不超过四个参数,使用R0-R3来传递,超过的部分使用栈来传递。
如果包含了double(64位)类型,需要8字节(64位)对齐,也就是说double类型只能放在R的偶数(4字节)+奇数(4字节)来存放,而不能使用奇数+偶数来存放。
3.栈的使用方法:
过程调用标准规定数据栈为FD类型,并且对数据栈的操作时要求8字节对齐。
-------------------------------------------------
协处理指令
ARM支持多达16个协处理器,ARM协处理器指令主要用于ARM处理器初始化ARM协处理器的数据处理操作,以及在ARM处理器的寄存器和协处理器的寄存器之间传送数据,以及在ARM协处理器的寄存器和存储器之间传送数据
ARM协处理器有5条指令:
CDP:协处理器数操作指令
LDC:协处理器数据加载指令
STC:协处理器数据存储指令
MCR:ARM处理器寄存器到协处理器寄存器数据传送指令
MRC:协处理器寄存器到ARM处理器寄存器数据传送指令
MCR指令格式:
MCR{} 协处理器编码,协处理器操作码1,源寄存器,目的寄存器1,目的寄存器2,协处理器操作码2
将ARM处理器的源寄存器中的数据传送到协处理器的目的寄存器1和目的寄存器2.
。。。。。。
-------------------------------------------------
信号量指令
。。。。。。