我将ARM Cortex-M的C程序中的二进制数据与GCC链接,如下所示:
arm-none-eabi-ld.exe -r -b binary -o html.o index.html
要处理数据,我有以下外部变量:
extern const unsigned char _binary_index_html_start;
extern const unsigned char _binary_index_html_end;
extern const uint32_t _binary_index_html_size;
static const char* html = &_binary_index_html_start;
static const size_t html_len = &_binary_index_html_size;
我不明白为什么我需要让_binary_index_html_size
变量的地址具有大小值?
这意味着_binary_index_html_size
变量的内存地址(指针)表示blob的大小值(以字节为单位)。当我调试它似乎是正确的,但对我来说,这似乎是一个非常奇怪的解决方案来解决这个问题。
修改
我猜这个的原因可能是:因为blob的大小永远不会大于本机数据大小(在我的情况下是2 ^ 32),而不是浪费空间并存储大小GCC只是创建一个指向内存地址,表示blob的大小。所以这个值是完全随机的,取决于其他代码(我测试了这个)。这似乎是一个聪明的事情,因为大小不占用空间并且指针在编译时被解析。因此,如果一个人不需要这个尺寸,就不会浪费空间
我想我会使用(&_binary_index_html_end) - (&_binary_index_html_start)
,这似乎更好,并得到所有编译器的支持。
答案 0 :(得分:1)
您正在处理的所有符号都是链接器脚本定义的变量,它们的访问方式与您完全相同。 ld documentation中非常明确地给出了对此的解释。
当用C等高级语言声明符号时,两个 事情发生。首先是编译器保留足够的空间 程序的内存保存符号的值。第二是 编译器在程序的符号表中创建一个条目 持有符号的地址。即符号表包含地址 保存符号值的内存块。
然后,稍后在文档中,我们可以找到以下内容。
相比之下,链接器脚本符号声明会创建一个条目 符号表但不为它们分配任何内存。因此他们是 没有价值的地址。
这意味着链接器定义变量的地址确实是它的实际值,这就是为什么你必须采用这样的地址才能读取与链接符号相关的值。