C编译器错误或程序错误?

Gro*_*uez 7 c embedded iar

我正在使用IAR C编译器来构建嵌入式微应用程序(特别是瑞萨的uPD78F0537).在这个应用程序中,我使用两个嵌套的for循环来初始化一些数据,如下面的MCVE所示:

#include <stdio.h>

#define NUM_OF_OBJS 254
#define MAX_OBJ_SIZE 4

unsigned char objs[NUM_OF_OBJS][MAX_OBJ_SIZE];
unsigned char srcData[NUM_OF_OBJS][MAX_OBJ_SIZE];

void main(void)
{
    srcData[161][2] = 10;

    int x, y;
    for (x = 0; x < NUM_OF_OBJS; x++)
    {
        for (y = 0; y < MAX_OBJ_SIZE; y++)
        {
            objs[x][y] = srcData[x][y];
        }
    }

    printf("%d\n", (int) objs[161][2]);
}
Run Code Online (Sandbox Code Playgroud)

输出值为0,而不是10.

编译器为for循环生成以下代码:

     13              int x, y;
     14              for (x = 0; x < NUM_OF_OBJS; x++)
   \   0006   14....         MOVW      DE,#objs
   \   0009   16....         MOVW      HL,#srcData
     15              {
     16                  for (y = 0; y < MAX_OBJ_SIZE; y++)
   \   000C   A0F8           MOV       X,#248
     17                  {
     18                      objs[x][y] = srcData[x][y];
   \                     ??main_0:
   \   000E   87             MOV       A,[HL]
   \   000F   95             MOV       [DE],A
     19                  }
   \   0010   86             INCW      HL
   \   0011   84             INCW      DE
   \   0012   50             DEC       X
   \   0013   BDF9           BNZ       ??main_0
     20              }  
Run Code Online (Sandbox Code Playgroud)

上述不工作:编译器显然预先计算NUM_OF_OBJS X MAX_OBJ_SIZE = 1016(0x3f8).该值用作计数器,但它被截断为8位(0xf8 == 248)并存储在8位寄存器"X"中.结果,只初始化了前248个字节的数据,而不是整个1016个字节.

我可以解决这个问题,但我的问题是:这是编译器错误吗?还是我忽略了什么?


更新

  • 该微控制器具有7KB的RAM,并且sizeof(int)== 2
  • 使用指针复制数据(例如,某些东西while (len-- > 0) *dst++ = *src++;)可以正常工作.

Gro*_*uez 1

我非常确信这是一个基于以下内容的编译器错误:

  • 使用指针(例如类似的东西while (len-- > 0) *dst++ = *src++;)复制数据效果很好。因此,这看起来不像是 RAM 大小、指针大小等问题。

  • NUM_OF_OBJS也许更相关:如果我只是用静态变量替换两个常量(或)之一MAX_OBJ_SIZE(从而防止编译器预先计算总计数),它就可以正常工作。

不幸的是,我联系了 IAR(提供了这个问题的链接),这是他们的答案:

很遗憾您没有许可证/支持协议 (SUA)。此案例所需的检查可能需要时间,我们(售后支持)优先考虑为拥有有效 SUA 的用户投入时间和精力。

以及一些不是特别有用的通用注释。

所以我想我会假设这是一个错误并在我的代码中解决它(有许多可能的解决方法,包括上面描述的两种)。