因为ARM的算术运算不支持直接操作内存地址,所以要把内存里的数据先加载进寄存器。ldr指令就是干这事的,称为间接取址模式。
一共有3*3九种模式,先是直接偏移,先偏移,后偏移三大类,指的是如何对源操作数操作,是直接使用,还是在加载前对源操作数操作(比如地址加个数值),还是在加载后对操作数操作
每个大类里分三个小类,分别指源操作数是立即数,寄存器,还是标量寄存器(比如对寄存器里的数向左偏移两位,即乘4)
汇编指令和对应的C代码如下
1 Immediate offset: 2 3 LDR R0, [R1, #4] 4 r0 = r1[1]; 5 6 Remember, again, the offset is in bytes, so #4 would point to the second word (long int) in our array, thus in C the array indice [1] would provide the correct data. 7 8 Register offset: 9 10 LDR R0, [R1, R2] 11 r0 = r1[r2]; 12 13 Scaled register offset: 14 15 LDR R0, [R1, R2, LSL #4] 16 r0 = r1[(r2 << 4)]; 17 18 Immediate pre-indexed: 19 20 LDR R0, [R1, #4]! 21 r1 += 4; r0 = *r1; 22 23 Register pre-indexed: 24 25 LDR R0, [R1, R2]! 26 r1 += r2; r0 = *r1; 27 28 Scaled register pre-indexed: 29 30 LDR R0, [R1, R2, LSL #2]! 31 r1 += (r2 << #2); r0 = *r1; 32 33 Immediate post-indexed: 34 35 LDR R0, [R1], #4 36 r0 = *r1; r1 += 4; 37 38 Register post-indexed: 39 40 LDR R0, [R1], R2 41 r0 = *r1; r1 += r2; 42 43 Scaled register post-indexed: 44 45 LDR R0, [R1, R2, LSL #2]! 46 r0 = *r1; r1 += (r2 << #2);
str指令是把寄存器里的数存到内存里,目标地址的计算方式与操作与ldr指令中源地址的计算方法与操作一样
Immediate offset:
LDR R0, [R1, #4] r0 = r1[1];
Remember, again, the offset is in bytes, so #4 would point to the second word (long int) in our array, thus in C the array indice [1] would provide the correct data.
Register offset:
LDR R0, [R1, R2] r0 = r1[r2];
Scaled register offset:
LDR R0, [R1, R2, LSL #4] r0 = r1[(r2 << 4)];
Immediate pre-indexed:
LDR R0, [R1, #4]! r1 += 4; r0 = *r1;
Register pre-indexed:
LDR R0, [R1, R2]! r1 += r2; r0 = *r1;
Scaled register pre-indexed:
LDR R0, [R1, R2, LSL #2]! r1 += (r2 << #2); r0 = *r1;
Immediate post-indexed:
LDR R0, [R1], #4] r0 = *r1; r1 += 4;
Register post-indexed:
LDR R0, [R1], R2 r0 = *r1; r1 += r2;
Scaled register post-indexed:
LDR R0, [R1, R2, LSL #2]! r0 = *r1; r1 += (r2 << #2);