为什么价值被覆盖?

时间:2014-09-16 12:23:26

标签: c atmel freertos cortex-m

首先,对不起,我知道这很长,人们可能不会阅读所有内容,但我认为需要非常详细的解释。

我试图在带有FreeRTOS的Cortex M4上使用Chan Fat文件获取长文件名。我有一个奇怪的事情,由于某种原因,指针被一段看似无关的代码覆盖。你期待堆栈溢出(哈哈!),但我的堆栈很大,我尝试从我第一次遇到这个问题时进一步增加它,我真的不认为它可以是的。

我有这段代码:

uint16_t w, *lfn;
lfn = dj->lfn;     
*tp = fno->lfname;
while ((w = *lfn++) != 0) 
{           /* Get an LFN char */
    if (i >= fno->lfsize - 1) 
    { 
       i = 0; 
       break; 
    }   /* Buffer overflow, no LFN */
    tp[i] = (TCHAR)w;
    i++;
}

lfn是指向16位值的指针。 w是一个16位值。

汇编程序中的行tp[i] = (TCHAR)w;如下:

6A7B        ldr r3, [r7, #0x24]
005B        lsls r3, r3, #1
68FA        ldr r2, [r7, #12]
4413        add r3, r2
897A        ldrh r2, [r7, #10]
801A        strh r2, [r3]

通过循环的前几次一切都很好。正如您所期望的那样,lfn在跳跃为2时从0x20009c68递增。但是,当lfn到达0x20009c72并且代码到达行tp[i] = (TCHAR)w;时,它会变得混乱。

前两行汇编程序取i的值,将其左移一,得到正确的偏移量。

接下来的两行将tp的地址放入r2,然后添加r3的内容,这又是必需的偏移量。

ldrh r2, [r7, #10] then puts w in r2 

最后,

strh r2, [r3]

将w存储到r3指向的位置,这是tp指向的必要位置。

lfn到达0x20009c72时,汇编程序的最后一行将0x20000061放入lfn。这是导致真正问题的一条线。在此之前,它正确地将r2 w存储到r3指向的位置。此时r3包含0x20009c48,r2包含0x00000061。但是,与以前不同,这会破坏lfn,并将0x20000061放入其中。它显然正在影响lfn本身。

在整段执行这段代码时,堆栈指针本身不会改变。

我想知道lfndj->lfn是指向uint16_t而不是有限大小数组的指针是否是一个显着点? dj是DIR类型的结构,定义如下:

typedef struct {
    FATFS*  fs;             /* Pointer to the owner file system object */
    WORD    id;             /* Owner file system mount ID */
    WORD    index;          /* Current read/write index number */
    DWORD   sclust;         /* Table start cluster (0:Root dir) */
    DWORD   clust;          /* Current cluster */
    DWORD   sect;           /* Current sector */
    BYTE*   dir;            /* Pointer to the current SFN entry in the win[] */
    BYTE*   fn;             /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
    WCHAR*  lfn;            /* Pointer to the LFN working buffer */
    WORD    lfn_idx;        /* Last matched LFN index number (0xFFFF:No LFN) */
} DIR;

WCHAR等于无符号的16位值。

0 个答案:

没有答案