我有一个汇编文件。我将使用此文件包含如下所示的二进制文件:
.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
然后在C文件中,我将调用该变量并使用该二进制文件的内容。
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;
}
问题是,在编译和执行后,“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 ...
下面是我的编译器和链接选项:
qcc -Vgcc_ntoaarch64le -c -Wp,-MMD,build/aarch64le-debug/src/imrdls.d,-MT,build/aarch64le-debug/src/imrdls.o -o build/aarch64le-debug/src/imrdls.o -Wall -fmessage-length=0 -g -O0 -fno-builtin src/imrdls.s
qcc -Vgcc_ntoaarch64le -c -Wp,-MMD,build/aarch64le-debug/src/Test.d,-MT,build/aarch64le-debug/src/Test.o -o build/aarch64le-debug/src/Test.o -Wall -fmessage-length=0 -g -O0 -fno-builtin src/Test.c
qcc -Vgcc_ntoaarch64le -o build/aarch64le-debug/Test build/aarch64le-debug/src/Test.o build/aarch64le-debug/src/imrdls.o
任何评论都会非常有用。谢谢。
如果您查看垃圾箱输出“7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00”,您可以看到它与精灵标题相同。 link
当使用.section指令创建新节时,必须提供该节的属性和类型。用这个替换你的程序集文件中的第一行应该工作:
.section .bindata , "a", @progbits
a
将该部分标记为可分配。 ("aw"
也会使它可写,但你不需要那些常数。你使用"aw"
相当于.data
,而不是.rodata
。)
如果未指定任何标志,则默认标志取决于节名称。如果无法识别段名,则默认情况下该段不具有任何标志:它不会在内存中分配,也不会在可写,也不可执行。该部分将包含数据。 Reference
您的数据位于具有非标准名称.bindata
的部分中。我不知道链接器放在哪里,但显然它没有映射到运行程序时从文件加载(或内存映射)的可执行段。
除非您确实需要相对于编译器生成的只读数据来控制所包含数据的布局,否则只需将数据放入.section .rodata
即可。
(我很惊讶链接器没有抱怨,并且你没有在运行时遇到段错误。我本来希望至少有一个段错误而不是默默地获取虚假数据。)