这一系列的ARM如何工作?

时间:2013-11-21 02:43:52

标签: assembly arm

我在计算此汇编代码的工作原理时遇到了一些麻烦。我知道它循环16次并更新每次迭代的总数。特别是在.L2标签的行上,自上一行以来不会给出分段错误:ldr ip,[ip,#0]重新分配ip?谁能解释一下这是如何工作的?提前感谢您的时间。

.L5:
    .word data
    .word total
_start:
    ldr ip, .L5
    mov r1, #0
    ldr r0, .L5+4
    mov r3, r1
    mov r2, r1
    ldr ip, [ip, #0]
    str r1, [r0, #0]
.L2:
    ldr r1, [ip, r3]
    add r3, r3, #4
    cmp r3, #64
    add r2, r2, r1
    str r2, [r0, #0]
    bne .L2

1 个答案:

答案 0 :(得分:1)

您的代码:

  • data中加载ip的地址,在total中加载r0的地址。
  • Zeroes注册r1r2r3
  • ip的内容加载到data,替换之前的内容(data的地址)。这不是段错误。您可以从内存加载到任何寄存器,包括您刚刚用于指定加载的有效地址的寄存器。所有这一切都是通常的:无论旧的值(在这种情况下,指针)都被新值(指针)替换。
  • 0存储到total
  • 重复16次:
    • 使用ip作为整数数组的基址,从基地址加载r1偏移r3的整数。
    • r1累积到注册表r2
    • r2存储到total

基于此,我认为data的类型为int*,而total的类型为int。因此,我对你的汇编程序的解释是:

Pseudocode-y C-like汇编程序

int* data;
int total;


void start(void){
    int** ip = &data;
    int*  r0 = &total;
    int r1=0, r2=r1, r3=r1;

    int* ipnew = *ip;
    *r0 = r1;/* total = 0; */

    do{
        r1 = *(int*)((char*)ipnew + r3);/* r1 = ipnew[r3/4]; */
        r3 += 4;
        r2 += r1;
        *r0 = r2;/* total = r2; */
    }while(r3 != 64);
}

Pure C

int* data;
int  total;

void start(void){
    int* arr = data;      /* ip */
    register int  sum = 0;/* r2 */
    register int  i   = 0;/* r3, divided by 4 */

    total = 0;

    do{
        sum   += arr[i++];/* r1 contains the value loaded from the array. */
        total  = sum;     /* r0 contains &total */
    }while(i != 16);
}