我有一个汇编文件。我将使用此文件包括如下所示的二进制文件:
move = random.choice([1, 3, 4, 5, 6, 7, 8, 9, 10])
然后在C文件中,我将校准该变量并使用该二进制文件的内容。
.section .bindata
.global imrdls_start
.type imrdls_start, @object
.global imr_SW_DL_start
.type imr_SW_DL_start, @object
.section .bindata
.balign 64
imrdls_start:
imr_SW_DL_start:
.incbin "file.bin"
.balign 1
imr_SW_DL_end:
.byte 0
问题是,编译并执行后,打印出的“ file.bin”的内容不正确。
预期结果是:00 1d 81 ff 00 fe 00 ff 00 1e 82 00 00 20 82 ...
垃圾输出打印为:7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 ...
下面是我的编译器和链接选项:
int main(void) {
extern uint8_t imrdls_start;
uint8_t *ptrToExpectedDL = &imrdls_start;
for(int i = 0; i < 135; i++)
{
printf("0x%02x ", ptrToExpectedDL[i]);
if((((i + 1) % 15) == 0)) printf("\n");
}
return EXIT_SUCCESS;
}
任何评论都将非常有帮助。谢谢。
答案 0 :(得分:2)
如果您查看垃圾输出“ 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00”,您会看到它与elf标头相同。 link
使用.section指令创建新节时,必须提供该节的属性和类型。以此替换您的程序集文件中的第一行应该起作用:
.section .bindata , "a", @progbits
a
将该节标记为可分配。 ("aw"
也可以使其可写,但是常量不需要。"aw"
等效于.data
,而不是.rodata
。)< / p>
如果未指定标志,则默认标志取决于节名称。如果无法识别该节的名称,则默认为该节不具有任何标志:它将不会在内存中分配,不可写,也不可执行。该部分将包含数据。 Reference
答案 1 :(得分:1)
您的数据位于具有非标准名称.bindata
的部分中。我不知道链接器将它放在哪里,但是很显然,它没有映射到在运行程序时从文件加载(或映射到内存)的可执行段中。
除非您确实需要控制包含的数据相对于编译器生成的只读数据的布局,否则只需将数据放入.section .rodata
中即可。
(令我惊讶的是,链接器没有抱怨,而且您在运行时没有遇到段错误。我希望至少要有段错误,而不是默默地获取虚假数据。)