- 内存访问指令:ldr和str
一般的指令都是对寄存器的操作,不能直接对内存进行操作,而ldr和sdr可以,也就是说只有ldr和str是对内存的操作指令,对内存的访问只能用ldr和str:
ldr — Load from memory into a register
str — Store from a register into memory
应用示例:
ldr r0, [r1]
//将R1中的值存到r0中
ldr r1, [r2, #16]
//将(r2+16)地址中的内容存到r1中
ldr r1, [r2], #4
//将r2地址中的内容存到r1中,同时r2=r2+4
str r1, [r2]
//将r1中的值存到r2所指定的地址中
str r1, [r2, #4]
//将r1中的值存到r2+4所指定的地址中
str r1, [r2], #4
//将r1中的值存到r2所指定的地址中, 同时r2=r2+4 - ldr伪指令
ldr 指令当它的第二个参数前面有”=” 时,表示大范围的地址读取伪指令,否则表示内存访问指令。为何要用ldr伪指令,因为32位的机器码有一部分位用来表示指令等其他信息,剩下的一部分位才去表示操作数,因此mov指令后只能跟简单的操作数,故在操作数复制时用ldr伪指令,在编译的时候处理替换为实际的汇编指令。
如果是简单的立即数,那么在汇编时会用mov指令替换伪指令,如:
ldr r0, =0x48000000
->
33f80030: e3a00312 mov r0, #1207959552 ; 0x48000000
如果是复杂的立即数,那么在汇编时会先将这个数存在内存中,然后用内存访问指令替换伪指令,如:
ldr r0, =0x4c000014
->
33f800ac: 4c000014 .word 0x4c000014
33f8000c: e59f0098 ldr r0, [pc, #152] ; 33f800ac
- 程序状态寄存器指令:msr和mrs
在ARM处理器中,提供了两条可以直接控制程序状态寄存器的指令msr和mrs指令,可以对状态寄存器CPSR和SPSR进行操作。
①、mrs:用于将程序状态寄存器的内容读写到通用寄存器中。
MRS指令的格式为:
MRS {条件} 通用寄存器,程序状态寄存器(CPSR或SPSR)
示例:
MRS R1, CPSR
// 将CPSR状态寄存器读取,保存到R1中
MRS R2, SPSR
//将SPSR状态寄存器读取,保存到R2中
②、msr:用于将操作数的内容读写到程序状态寄存器的特定域中。
MSR指令的格式为:
MSR {条件} 程序状态寄存器(CPSR或SPSR)_<域>,操作数
其中,<域>用于设置程序状态寄存器中需要操作的位,32位的程序状态寄存器可分为4个域:
位[31:24]为条件标志位域,用f表示;
位[23:16]为状态位域,用s表示;
位[15:8]为扩展位域,用x表示;
位[7:0]为控制位域,用c表示;
示例:
MSR CPSR, R0
//读R0的内容写到CPSR
MSR SPSR, R0
//读R0的内容写到SPSR
MSR CPSR_c, R0
//读R0的内容到CPSR,但仅仅修改CPSR中的控制位域 - AND、ORR、EOR、BIC
①、逻辑与指令:AND
指令的语法格式:
AND {<cond>} {S} <Rd>, <Rn>, <shifter_operand>
将寄存器<Rn>
的值与第二源操作数<shifter_operand>
的值按位做“逻辑与”操作,结果保存到<Rd>
中。
②、逻辑或指令:ORR
指令的语法格式:
ORR {<cond>} {S} <Rd>, <Rn>, <shifter_operand>
将寄存器<Rn>
的值与第二源操作数<shifter_operand>
的值按位做“逻辑或”操作,结果保存到<Rd>
中。
③、逻辑异或指令:EOR
指令的语法格式
EOR {<cond>} {S} <Rd>, <Rn>, <shifter_operand>
将寄存器<Rn>
的值与第二源操作数<shifter_operand>
的值按位做“异或”操作,相同为0,相异为1,结果保存到<Rd>
中。
④、位清零指令:BIC
指令的语法格式:
BIC {<cond>} {S} <Rd>, <Rn>, <shifter_operand>
将寄存器<Rn>
的值与第二源操作数<shifter_operand>
的值的反码按位做“逻辑与”操作,结果保存到<Rd>
中。
示例:
BIC R0, R0, #0x1011
//清除R0中位0、1和3,其余位保持不变 协处理器指令MCR和MRC
①、MCR:将arm寄存器<Rd>
的值传送到协处理寄存器cpu_num中。
指令的语法格式:
MCR {<cond>} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
其中:
<coproc>
:指定协处理器的编号,标准的协处理器的名字为p0,p1,…,p15;
<opcode_1>
:指定协处理器执行的操作码,确定哪一个协处理器指令将被执行;
<Rd>
:确定哪一个arm寄存器的数值将被传送;
<CRn>
:确定包含第一个操作数的协处理器寄存器;
<CRm>
:确定包含第二个操作数的协处理器寄存器;
<opcode_2>
:指定协处理器执行的操作码,确定哪一个协处理器指令将被执行,通常与<opcode_1>
配合使用。
指令示例:
MCR p14, 1, R7, c7, c12, 6
//将arm寄存器R7中的值传送到协处理器p14的寄存器c7中,第一个操作数opcode_1=1,第二个操作数opcode_2=6
②、MRC:将协处理寄存器cpu_num寄存器中的值传送到arm寄存器<Rd>
中。
指令的语法格式:
MRC {<cond>} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
其中:
<coproc>
:指定协处理器的编号,标准的协处理器的名字为p0,p1,…,p15;
<opcode_1>
:指定协处理器执行的操作码,确定哪一个协处理器指令将被执行;
<Rd>
:确定协处理器寄存器的数值将被传送哪一个arm寄存器;
<CRn>
:确定包含第一个操作数的协处理器寄存器;
<CRm>
:确定包含第二个操作数的协处理器寄存器;
<opcode_2>
:指定协处理器执行的操作码,确定哪一个协处理器指令将被执行,通常与<opcode_1>
配合使用。
指令示例:
MRC p15, 5, R4, c0, c2, 3
//协处理器源寄存器c0和c2,目标寄存器为arm寄存器R4,第一个操作数opcode_1=5,第二个操作数opcode_2=3STMIB和LDMIA
STMIB R0!,{R1,R2}
//是指将R1,R2的值保存到R0指向的存储单元中(R0自动加1)
LDMIA R0!,{R1,R2}
//是指将R0指向的单元中的数据读出到R1,R2中(R0自动加1)
ARM指令搜集
最新推荐文章于 2023-06-19 06:55:17 发布