【发布时间】:2016-05-29 17:48:28
【问题描述】:
我写了一个简单的测试代码,我无意中发现结构中的查找表似乎分配在闪存中,我不知道如何解释。这是简单的代码:
#include <avr/io.h>
#include <avr/delay.h>
#include <stdlib.h>
struct PEC {
uint8_t lookup[31] ;
};
uint8_t r;
int main() {
uint8_t r = rand() % 20;
while(1) {
struct PEC access = {
0x00U, 0x07U, 0x0EU, 0x09U, 0x1CU, 0x1BU, 0x12U, 0x15U,
0x38U, 0x3FU, 0x36U, 0x31U, 0x24U, 0x23U, 0x2AU, 0x2DU,
0x70U, 0x77U, 0x7EU, 0x79U, 0x6CU, 0x6BU, 0x62U, 0x65U,
0x48U, 0x4FU, 0x46U, 0x41U, 0x54U, 0x53U} ;
volatile uint8_t v = access.lookup[r] ;
_delay_ms(1500);
}
}
编译器有输出:
AVR 内存使用情况
设备:atmega168
程序:870 字节(5.3% 已满) (.text + .data + .bootloader)
数据:5 个字节(0.5% 已满) (.data + .bss + .noinit)
如果分配是在 Flash 中,您能解释一下吗? 我认为在执行期间查找表不在那个堆栈上,我错了吗? 为什么没有在 Stack 上分配结构?
【问题讨论】:
-
查找表初始化值存储在闪存中。它们在运行时被复制到堆栈以初始化结构。所以结构 is 在堆栈上(您可以通过查看汇编代码来确认这一点)。请注意,内存使用情况报告不会告诉您任何有关堆栈使用情况的信息。
-
这是一个查找表。你不希望它在 Flash 中?
-
你的结构被初始化了。初始化值必须存储在非易失性存储器中,即闪存。然后程序永远不会修改结构内容。所以也许编译器意识到结构的 RAM 副本不是必需的,因此它只使用闪存副本。
-
@Martin James 我不会在 Flash 中这样做,但我很困惑,因为我没有使用 attribute 宏来告诉编译器我想要它的位置!!
-
我相信您在
main()中声明的access结构将被分配到堆栈上。您可能可以通过查看生成的汇编代码来判断:main的序言可能会将SP减少 32 个字节左右(结构体为 31,局部变量r为 1(这将阻止您访问同名的全局变量!)作为@user3386109 和@kkrambo 状态,Flash 中的数据正在初始化...它被复制到本地(堆栈)变量accessmain开头的某处。