我在计算此汇编代码的工作原理时遇到了一些麻烦。我知道它循环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
答案 0 :(得分:1)
您的代码:
data
中加载ip
的地址,在total
中加载r0
的地址。r1
,r2
和r3
ip
的内容加载到data
,替换之前的内容(data
的地址)。这不是段错误。您可以从内存加载到任何寄存器,包括您刚刚用于指定加载的有效地址的寄存器。所有这一切都是通常的:无论旧的值(在这种情况下,指针)都被新值(指针)替换。 0
存储到total
。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);
}