因為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);