ldrsh

时间:2016-08-11 14:41:17

标签: gcc arm cortex-m

大家好,我在同一个地方多次在我的皮层m1上有HardFault异常。我已经实现了HardFault,我可以读取堆栈寄存器:

stacked_r0 unsigned int 0x4(Hex)
stacked_r1 unsigned int 0x60905f98(Hex)
stacked_r2 unsigned int 0x0(Hex)
stacked_r3 unsigned int 0x6092304b(十六进制)
stacked_r12 unsigned int 0x60922ff8(Hex)
stacked_lr unsigned int 0x60810be3(Hex)
stacked_pc unsigned int 0x60810ce2(Hex)
stacked_psr unsigned int 0x41000000(Hex)

堆叠式PC的操作是: 60810ce2:ldrsh r2,[r3,r2]

为什么会导致错误?

UPD 我已经重新安排了变量,现在它已经从freertos代码调用的memcpy中崩溃了

stacked_r0 unsigned int 0x6090c858(Hex)
stacked_r1 unsigned int 0x6091f8b4(Hex)
stacked_r2 unsigned int 0x3c(Hex)
stacked_r3 unsigned int 0x6091f8a4(Hex)
stacked_r12 unsigned int 0x280(Hex) stacked_lr unsigned int 0x60827f89(Hex)
stacked_pc unsigned int 0x6082b0dc(Hex)
stacked_psr unsigned int 0x1000000(Hex)

6082b0ba:bne.n 0x6082b120

6082b0bc:添加r5,r2,#0

6082b0be:添加r4,r0,#0

6082b0c0:subs r5,#16

6082b0c2:lsrs r5,r5,#4

6082b0c4:添加r5,#1

6082b0c6:lsls r5,r5,#4

6082b0c8:添加r1,r1,r5

6082b0ca:ldr r6,[r3,#0]

6082b0cc:str r6,[r4,#0]

6082b0ce:ldr r6,[r3,#4]

6082b0d0:str r6,[r4,#4]

6082b0d2:ldr r6,[r3,#8]

6082b0d4:str r6,[r4,#8]

6082b0d6:ldr r6,[r3,#12]

6082b0d8:添加r3,#16

6082b0da:str r6,[r4,#12]

6082b0dc:添加r4,#16

1 个答案:

答案 0 :(得分:1)

使用ldrsh生成对齐的编译器的简单示例:

short more_fun ( short );
short fun ( short a )
{
    unsigned int ra;
    short x[16];
    for(ra=0;ra<16;ra++)
    {
        a+=more_fun(x[ra]);
    }
    return(a);
}

arm-none-eabi-gcc -mthumb -O2 -c so.c -o so.o -march = armv6-m arm-none-eabi-objdump -D so.o

00000000 <fun>:
   0:   b570        push    {r4, r5, r6, lr}
   2:   b088        sub sp, #32
   4:   0004        movs    r4, r0
   6:   466d        mov r5, sp
   8:   ae08        add r6, sp, #32
   a:   2300        movs    r3, #0
   c:   5ee8        ldrsh   r0, [r5, r3]
   e:   f7ff fffe   bl  0 <more_fun>
  12:   3502        adds    r5, #2
  14:   1904        adds    r4, r0, r4
  16:   b224        sxth    r4, r4
  18:   42b5        cmp r5, r6
  1a:   d1f6        bne.n   a <fun+0xa>
  1c:   0020        movs    r0, r4
  1e:   b008        add sp, #32
  20:   bd70        pop {r4, r5, r6, pc}
  22:   46c0        nop         ; (mov r8, r8)

堆栈保持对齐,堆栈操作,推送,弹出和堆栈帧都是8个字节(两个字)的倍数。

数组在堆栈上,它们使用r5作为数组的索引,看起来像ldrsh需要两个寄存器,因此它们将r3设置为零,这样它们就可以有第二个寄存器。这里的关键是它们开始对齐,sp地址至少有低三位零,假设此代码之外的每个人都符合约定。然后代码每次通过循环向r5添加2,保持指向阵列的指针在半字边界上对齐,对于每次使用ldrsh,低位对于地址保持为零。没有对齐问题。

请提供类似的例子,可能是代码片段,但肯定是未对齐的ldrsh周围的相关片段。