1. 字 加载存储指令
● [<Rn>, #+/-<offset_12>]
MOV R1, #0x100
MOV R0, #0x8
STR R0, [R1] ;address 0x100 {0x00 00 00 08}
STR R0, [R1, #4] ;address 0x104 {0x00 00 00 08}
MOV R1, #0x100
LDR R2, [R1] ; 将内存单元R1中的字读取到R2寄存器中 R2 {0x00 00 00 08}
LDR R3, [R1, #4] ; 将内存单元R1+4中的字读取到R3寄存器中 R3 {0x00 00 00 08}
● [<Rn>, +/-]
MOV R1, #0x100
MOV R0, #0x8
STR R0, [R1] ;address 0x100 {0x00 00 00 08}
STR R0, [R1, #4] ;address 0x104 {0x00 00 00 08}
MOV R2, #0
MOV R1, #0x104
LDR R3, [R1, R2] ; 将内存单元R1+R2(0x104)中的字读取到R3寄存器中 R3 {0x00 00 00 08}
LDR R4, [R1, -R2] ; 将内存单元R1-R2(0x100)中的字读取到R4寄存器中 R4 {0x00 00 00 08}
● [<Rn>, +/-,#<shift_imm>]
MOV R1, #0x100
MOV R2, #1
MOV R0, #0x8
STR R0, [R1, #4] ;address 0x104 {0x00 00 00 08}
LDR R0, [R1, R2 , LSL #2] ; 将地址单元(R1+R2*4)(0x104)中的数据读取到R0{0x08}
MOV R2, #0x08
LDR R3, [R1, R2 , LSR #1] ; 将地址单元(R1+R2/2)(0x104)中的数据读取到R3{0x08}
LDR R4, [R1, R2 , ASR #1] ; 将地址单元(R1+R2/2)(0x104)中的数据读取到R4{0x08}
LDR R5, [R1, R2 , ROR #1] ; 将地址单元(R1+R2/2)(0x104)中的数据读取到R5{0x08}
LDR R6, [R1, R2 , RRX] ; 将地址单元(R1+R2/2)(0x104)中的数据读取到R6{0x08}
● [<Rn>, #+/-<offset_12>]!
MOV R1, #0x100
LDR R2, [R1, #4]! ; 将内存单元(R1+4)中数据读取到R0中,同时R1=R1+4{0x104}
LDR R3, [R1, #-4]! ; 将内存单元(R1-4)中数据读取到R0中,同时R1=R1-4{0x100}
● [<Rn>, +/-]!
MOV R2, #0x04
MOV R1, #0x100
LDR R0, [R1, R2]! ; 将内存单元(R1+R2)中的数据读取到R0中,同时R1=R1+R2{0x104}
LDR R0, [R1, -R2]! ; 将内存单元(R1+R2)中的数据读取到R0中,同时R1=R1-R2{0x100}
● [<Rn>, +/-, #<shift_imm>]!
MOV R2, #0x04
MOV R1, #0x100
LDR R0, [R1, R2, LSL #2]! ; 将内存单元(R1+R2*4)中的数据读取到R0中,
; 同时R1=R1+R2*4{0x100 + 0x10 = 0x110}
;{shift ... LSR,ASR,ROR, RRX}
● [<Rn>], #+/-<offset_12>
MOV R1, #0x100
LDR R0, [R1], #4 ; 将地址为R1{0x100}的内存单元数据读取到R0中,然后R1=R1+4{0x104}
LDR R0, [R1], #-4 ; 将地址为R1{0x104}的内存单元数据读取到R0中,然后R1=R1-4{0x100}
● [<Rn>], +/-
MOV R1, #0x100
MOV R2, #0x4
LDR R0, [R1], R2 ; 将地址为R1(0x100)的内存单元数据读取到R0中,然后R1=R1+R2{x0104}
LDR R0, [R1], -R2 ; 将地址为R1(0x104)的内存单元数据读取到R0中,然后R1=R1-R2{0x100}
● [<Rn>], +/-,#<shift_imm>
MOV R2, #0x40
LDR R0, [R1], R2, LSL #2 ; 将地址为R1(0x100)的内存单元数据读取到R0中,然后R1=R1+R2*4(0x200)
LDR R0, [R1], R2, LSR #2 ; 将地址为R1(0x200)的内存单元数据读取到R0中,然后R1=R1+R2/4 (0x210)
LDR R0, [R1], R2, ASR #2 ; 将地址为R1(0x210)的内存单元数据读取到R0中,然后R1=R1+R2/4 (0x220)
LDR R0, [R1], R2, ROR #2 ; 将地址为R1(0x220)的内存单元数据读取到R0中,然后R1=R1+R2/4 (0x230)
LDR R0, [R1], R2, RRX ; 将地址为R1的内存单元数据读取到R0中,然后R1=R1+R2/2 (0x250)
2. 字节/半字 加载存储指令
2.1 原码 补码
-
计算机指令参与运算的是补码
源码 = 补码 按位取反 + 1MOV R0, #-9 ;R0 {0b11111111111111111111111111110111} MOV R1, #9 ;R1 {0b00000000000000000000000000001001}
2.2 字节/半字 存储加载
● [<Rn>, #+/-<offset_8>]
MOV R1, #0x100
MOV R0, #-9
STR R0, [R1] ;address 0x100 {0xff ff ff f7} or {0b11111111111111111111111111110111}
MOV R0, #0
LDRSB R0, [R1] ; 将内存单元R1中的有符号字节数据读取到R0{0b11111111111111111111111111110111}
; R0中高24位设置成该字节数据的符号位
LDRSB R0, [R1, #1] ; 将内存单元(R1+1)中的有符号字节数据读取到R0{0xffffffff = -1}
; R0中高24位设置成该字节数据的符号位
● [<Rn>, #+/-<offset_8>]!
MOV R1, #0x100
MOV R0, #-9
STR R0, [R1] //address 0x100 {0xff ff ff f7}
LDRSH R7, [R1, #0]! //将内存单元(R1+0)中的半字数据读取到R7中{0xff ff ff f7},R7中高16位设置成
//该半字的符号位; R1=R1 + 0
LDRSH R7, [R1, #2]! //将内存单元(R1+2)中的字节数据读取到R7中{0xffffffff},R7中高16位设置成
//该半字的符号位; R1=R1+2
● [<Rn>, +/-<Rm>]!
MOV R1, #0x100
MOV R0, #-9
MOV R2, #2
STR R0, [R1] //address 0x100 {0xff ff ff f7}
LDRH R0, [R1, R2]! //将内存单元(R1+R2)中的半字数据读取到R0中{0x0000ffff},R0中高16位
//设置成0; R1=R1+R2(0x102)
LDRH R0, [R1, -R2]! //将内存单元(R1-R2)中的半字数据读取到R0中{0x0000fff7},R0中高16位
//设置成0; R1=R1-R2 (0x100)
● [<Rn>, +/-<Rm>]
MOV R1, #0x100
MOV R0, #-9
MOV R2, #2
STRH R0, [R1, R2]! // 将R0中的低16位数据保存到内存单元(R1+R2){0x102}中{fff70000}
STRH R0, [R1, -R2] // 将R0中的低16位数据保存到内存单元(R1-R2){0x100}中{fff7fff7}
● [<Rn>], #+/-<offset_8>
MOV R1, #0x100
MOV R0, #-9
STRH R0, [R1], #8 //将R0中的低16位数据保存到内存单元(R1){0x100}中,同时,指令执行后
//R1=R1+8{0x108}
STRH R0, [R1], #-8 //将R0中的低16位数据保存到内存单元(R1) {0x108}中,同时,指令执行后
//R1=R1-8{0x100}
● [<Rn>], +/-<Rm>
STRH R0, [R1], R2 //将R0中的低16位数据保存到内存单元(R1)中,同时,
//指令执行后R1=R1+R2
STRH R0, [R1], -R2 //将R0中的低16位数据保存到内存单元(R1)中,同时,
//指令执行后R1=R1-R2
3. 连续字加载/存储指令
● IA (Increment After):事后递增方式。
MOV R13, #0x100
MOV R1, #0x100
MOV R5, #1
MOV R6, #2
MOV R7, #3
MOV R8, #4
STMIA R1,{R5-R8} // address 0x100{0x00000001,0x00000002,0x00000003,0x00000004}
LDMIA R1,{R2-R5} //将内存单元(0x100)到(0x100 + 12)四个字数据读取到R2~R5的寄存器中
● IB (Increment Before):事先递增方式。
MOV R13, #0x100
MOV R1, #0x100
MOV R5, #1
MOV R6, #2
MOV R7, #3
MOV R8, #4
STMIB R1,{R5-R8} // address 0x104{0x00000001,0x00000002,0x00000003,0x00000004}
LDMIB R1,{R2-R5} //将内存单元(0x104)到(0x104 + 12)四个字数据读取到R2~R5的寄存器中
● DA (Decrement After):事后递减方式。
MOV R13, #0x10000
MOV R1, #0x1000
MOV R5, #1
MOV R6, #2
MOV R7, #3
MOV R8, #4
STMDA R1,{R5-R8} // address 0x1000-0x12 {0x00000001,0x00000002,0x00000003,0x00000004}
LDMDA R1,{R2-R5} // address 0x1000-0x12 ,四个字数据读取到R2~R5的寄存器中
● DB (Decrement Before):事先递减方式。
MOV R13, #0x10000
MOV R1, #0x1000
MOV R5, #1
MOV R6, #2
MOV R7, #3
MOV R8, #4
STMDB R1,{R5-R8} // address 0x1000-0x16 {0x00000001,0x00000002,0x00000003,0x00000004}
LDMDB R1,{R2-R5} // address 0x1000-0x16 ,四个字数据读取到R2~R5的寄存器中