ARM 汇编指令
ARM 汇编指令
BIC 指令
用于清除操作数1的某些位,并把结果放置到目的寄存器中。
BIC R0, R0, #0xF0000000 @ 将R0高4位清零并将结果储存到R0
TST 指令
逻辑处理指令,用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的与运算,并根据运算结果更新CPSR中条件标志位的值。当前运算结果为1,则Z=0;当前运算结果为0,则Z=1。
TST R0 , #0x2 @进行and运算,如果bit_1为1,zero=0;
@如果bit_1为0,则zero=1,即该指令测试bit_1是否为0。
BNE LED_BLINK @非零则跳转,若zero==0,跳转到led_blink处执行;
@若zero==1,则继续执行下一步指令
CPS 指令
改变处理器状态寄存器(CPSR)的指令。
CPS<effect>{<q>} <iflags> {, #<mode>}
CPS{<q>} #<mode>
<effect> 影响CPSR寄存器的A,I,F位。比如:
IE 中断使能,将I位设置为0。
ID 中断禁止,将I位设置为1。
如<effect>被指定,<iflags>指定影响CPSR的位。
如<effect>未指定,则<iflags>无效,#<mode>指定新的模式。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
<iflags> a 影响CPSR.A
i 影响CPSR.I
f 影响CPSR.F
<mode> 制定新的模式
DMB & DSB & ISB 指令
DMB
数据存储器隔离。DMB 指令保证: 仅当所有在它前面的存储器访问操作
都执行完毕后,才提交(commit)在它后面的存储器访问操作。
DSB
数据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作
都执行完毕后,才执行在它后面的指令(亦即任何指令都要等待存储器访 问操作——译者注)
ISB
指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执
行完毕之后,才执行它后面的指令。
MRS & MSR 指令
MRS{<cond>}<Rd>, CPSR
MRS{<cond>}<Rd>, SPSR
MSR{<cond>} CPSR_<fields>, #<immediate>
MSR{<cond>} CPSR_<fields>, <Rm>
MSR{<cond>} CPSR_<fields>, #<immediate>
MSR{<cond>} CPSR_<fields>, <Rm>
<cond>为指令执行的条件码。当<cond>忽略时指令为无条件执行。
<fields>设置状态寄存器中需要操作的位。状态寄存器的32位可以分为4个8位的域:
f: 指示bits[31 : 24],又名条件标志位域
s: 指示bits[23 : 16],又名状态标志位域
x: 指示bits[15 : 8], 又名扩展位域
c: 指示bits[7 : 0],又名控制位
<immediate>为将要传送到状态寄存器中的立即数。
<Rm>寄存器包含将要传送到状态寄存器中的数据。
B 指令
B {cond} label
跳转指令,{cond}
条件如下:
符号 | 条件 | 标志位 |
---|---|---|
EQ | 相等(EQual) | Z==1 |
NE | 不相等(NotEqual) | Z==0 |
CS/HS | 进位(CarrySet) 无符号数大于或等于 |
C==1 |
CC/LO | 未进位(CarryClear) 无符号小于 |
C==0 |
MI | 负数(MInus) | N==1 |
PL | 非负数 | N==0 |
VS | 溢出 | V==1 |
VC | 非溢出 | V==0 |
HI | 无符号数大于 | C==1 && Z==0 |
LS | 无符号数小于等于 | C==0 || Z==1 |
GE | 带符号数大于等于 | N==V |
LT | 带符号数小于 | N!=V |
GT | 带符号数大于 | Z==0 && N==V |
LE | 带符号数小于等于 | Z==1 || N!=V |
AL | 总是 | - |
MRC 指令
MRC<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}
{<c>} 指令执行的条件码。当<cond>忽略时指令为无条件执行。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
<coproc> 协处理器名称,通常协处理器名称为p0-p15。
<opc1> 操作数1。
<Rt> 第一目标寄存器。
<Rt2> 第二目标寄存器。
<CRm> 指定协处理器寄存器。
MRC指令将协处理器的寄存器中数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。
MCR 指令
MCR<c> <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}
{<c>} 指令执行的条件码。当<cond>忽略时指令为无条件执行。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
<coproc> 协处理器名称,通常协处理器名称为p0-p15。
<opc1> 操作数1。
<Rt> 第一目标寄存器。
<Rt2> 第二目标寄存器。
<CRm> 指定协处理器寄存器。
MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。
MRRC(MRC2)指令
MRRC{2}{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>
{2} 指定的话使用T2/A2编码,不指定的话为T1/A1编码。
{<c>} 指令执行的条件码。当<cond>忽略时指令为无条件执行。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
<coproc> 协处理器名称,通常协处理器名称为p0-p15。
<opc1> 操作数1。
<Rt> 第一目标寄存器。
<Rt2> 第二目标寄存器。
<CRm> 指定协处理器寄存器。
同MRC
指令功能相同,都是从协处理器向cpu
寄存器传输数据,MRRC
传输数据64bit
数据到两个寄存器。
MCRR(MCR2)指令
MCRR{2}{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>
{2} 指定的话使用T2/A2编码,不指定的话为T1/A1编码。
{<c>} 指令执行的条件码。当<cond>忽略时指令为无条件执行。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
<coproc> 协处理器名称,通常协处理器名称为p0-p15。
<opc1> 操作数1。
<Rt> 第一目标寄存器。
<Rt2> 第二目标寄存器。
<CRm> 指定协处理器寄存器。
同MCR
指令功能相同,都是从协处理器向cpu
寄存器传输数据,MCRR
传输数据64bit
数据到两个寄存器。
STM 指令
STMFD{<c>}{<q>} <Rn>{!}, <registers> @ Full Descending
STMFA{<c>}{<q>} <Rn>{!}, <registers> @ Full Ascending
STMED{<c>}{<q>} <Rn>{!}, <registers> @ Empty Descending
STMEA{<c>}{<q>} <Rn>{!}, <registers> @ Empty Ascending
STMIA{<c>}{<q>} <Rn>{!}, <registers> @ Increase After
STMIB{<c>}{<q>} <Rn>{!}, <registers> @ Increase Before
STMDA{<c>}{<q>} <Rn>{!}, <registers> @ Decrease After
STMDB{<c>}{<q>} <Rn>{!}, <registers> @ Decrease Before
{<c>} 指令执行的条件码。当<cond>忽略时指令为无条件执行。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
<Rn> 指定寄存器。可以指定为SP。
{!} 将修改后的值储存到<Rn>寄存器,未指定时,不会改变<Rn>寄存器的值。
<registers> 指定一个或多个寄存器以逗号隔离,以{}包含。低地址的寄存器储存在低地址内存空间。
STM = STMIA = STMEA
将<registers>
中的值储存到<Rn>
寄存器的值的地址上。
LD : load 加载,出栈操作
ST : store 存储,入栈操作
M : multi 多次
F: full 满栈,SP指向最后一个数据
E: empty 空栈,SP指向最后一个数据相邻的下一个可写入存储单元
D: descending 递减,代表栈的增长方向
A: ascending 递增,代表栈的增长方向
我们一般使用FD(Full Descending)类型的数据栈!
LDM 指令
LDMFD{<c>}{<q>} <Rn>{!}, <registers> @ Full Descending
LDMFA{<c>}{<q>} <Rn>{!}, <registers> @ Full Ascending
LDMED{<c>}{<q>} <Rn>{!}, <registers> @ Empty Descending
LDMEA{<c>}{<q>} <Rn>{!}, <registers> @ Empty Ascending
LDMIA{<c>}{<q>} <Rn>{!}, <registers> @ Increase After
LDMIB{<c>}{<q>} <Rn>{!}, <registers> @ Increase Before
LDMDA{<c>}{<q>} <Rn>{!}, <registers> @ Decrease After
LDMDB{<c>}{<q>} <Rn>{!}, <registers> @ Decrease Before
{<c>} 指令执行的条件码。当<cond>忽略时指令为无条件执行。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
<Rn> 指定寄存器。可以指定为SP。
{!} 将修改后的值储存到<Rn>寄存器,未指定时,不会改变<Rn>寄存器的值。
<registers> 指定一个或多个寄存器以逗号隔离,以{}包含。低地址的寄存器储存在低地址内存空间。
LDM = LDMIA = LDMFD
与STM
相反操作。
PUSH 指令
PUSH{<c>}{<q>} <registers> Standard syntax @ 等价于以下指令
STMDB{<c>}{<q>} SP!, <registers> Equivalent STM syntax
POP 指令
POP{<c>}{<q>} <registers> Standard syntax @ 等价于以下指令
LDM{<c>}{<q>} SP!, <registers> Equivalent LDM syntax
LSR & LSL 指令
LSR{S}{<c>}{<q>} {<Rd>,} <Rm>, #<imm>
LSL{S}{<c>}{<q>} {<Rd>,} <Rm>, #<imm5>
{S} 是否影响标志位。
{<c>} 指令执行的条件码。当<cond>忽略时指令为无条件执行。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
{<Rd>,} 指定目标寄存器。
<Rm> 操作的寄存器。
#<imm5> 立即数。
LSL
逻辑左移,将操作数向左移位,低位补零,移除的高位进行丢弃。
LSR
逻辑右移,将操作数向右移位,高位补零,移除的低位进行丢弃。
MOV R0, #5
MOV R1, R0, LSL #2
上述命令,就是将5
存储到r0
寄存器上, 然后将r0
逻辑左移两位位后传送到r1
寄存器中。
ASR 指令
ASR{S}{<c>}{<q>} {<Rd>,} <Rm>, #<imm>
ASR
算术右移,算术右移符号位要一起移动,并且在左边补上符号位,也就是如果符号位是1
就补1
符号位是0
就补0
。比如:11100
算术右移一位为11110
。算术左移和算术右移主要用来进行有符号数的倍增、减半,逻辑左移和逻辑右移主要用来进行无符号数的倍增、减半。
CLZ 指令
CLZ{<c>}{<q>} <Rd>, <Rm>
{<c>} 指令执行的条件码。当<cond>忽略时指令为无条件执行。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
<Rd> 指定目标寄存器。
<Rm> 操作的寄存器。
CLZ
指令返回操作数二进制编码中第一个1
前0
的个数。如果操作数为0
,则指令返回32
;如果操作数二进制编码第31
位为1
,指令返回0
。例如:
MOV R0, #0x1F @ 0b0000 0000 0000 0000 0001 1111
CLZ R1, R0 @ R1 = 27
MOV R0, #0x17 @ 0b0000 0000 0000 0000 0001 0111
CLZ R1, R0 @ R1 = 27
{<c>} 指令执行的条件码。当<cond>忽略时指令为无条件执行。
{<q>} 修饰符,通常为.N和.W,.N使用16位编码,.W使用32为编码,未指定时由编译器自动选择。
<Rd> 指定目标寄存器。
<Rm> 操作的寄存器。
CLZ
指令返回操作数二进制编码中第一个1
前0
的个数。如果操作数为0
,则指令返回32
;如果操作数二进制编码第31
位为1
,指令返回0
。例如:
MOV R0, #0x1F @ 0b0000 0000 0000 0000 0001 1111
CLZ R1, R0 @ R1 = 27
MOV R0, #0x17 @ 0b0000 0000 0000 0000 0001 0111
CLZ R1, R0 @ R1 = 27