欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ARM 汇编指令

程序员文章站 2022-07-03 09:06:16
...

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)类型的数据栈!

ARM 汇编指令

参考资料

参考资料

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指令返回操作数二进制编码中第一个10的个数。如果操作数为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指令返回操作数二进制编码中第一个10的个数。如果操作数为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