打印
[DemoCode下载]

arm汇编指令

[复制链接]
976|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
跟屁虫|  楼主 | 2016-2-29 20:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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。


沙发
跟屁虫|  楼主 | 2016-2-29 20:08 | 只看该作者
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。

使用特权

评论回复
板凳
跟屁虫|  楼主 | 2016-2-29 20:09 | 只看该作者
多寄存器加载存储指令

主要用途现场保护,数据复制,参数传递,有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:控制位掩码域


使用特权

评论回复
地板
cowboy2014| | 2016-3-5 20:11 | 只看该作者
现在正在学习汇编,汇编语言如何与C语言对应起来呢?

使用特权

评论回复
5
mintspring| | 2016-3-6 22:37 | 只看该作者
Rm:寄存器Rm指定转移目标,Rm的bit【0】=1,跳转时自动将cpsr的标志位T置位,就是解释为Thumb,否则解释为ARM。

使用特权

评论回复
6
quray1985| | 2016-3-7 10:14 | 只看该作者
伪指令和指令的区别是什么呢
自己定义的是不是算伪指令呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

245

帖子

2

粉丝