同一汇编文件的函数/符号链接时会重排吗?符号顺序与连续性有保障吗?
问题:运行时复制汇编函数时,如何保障起止符号的顺序与内存连续性?
我编写了一段需要在运行时复制的汇编代码(复制逻辑由C代码实现),因此需要获取该函数的大小。我在汇编中按如下方式编写函数:
.globl function_foo function_foo: ... ... .globl function_foo_end function_foo_end:
在C代码中:
extern void function_foo(void); extern void function_foo_end(void); memcpy(dest, function_foo, (uintptr_t)function_foo_end - (uintptr_t)function_foo);
目前代码运行正常,但我担心链接过程中符号会被重排(例如function_foo_end被移至function_foo之前),或者function_foo与function_foo_end在内存中不连续,导致memcpy复制错误的大小。请问这些符号是否能保证顺序及内存连续性?
回答
符号的顺序与连续性是有保障的,只要你在汇编源文件里将
function_foo_end放在function_foo的指令之后,链接器就不会调整二者的相对顺序,也不会在两者之间插入其他代码——前提是你没有使用特殊的链接脚本或编译选项刻意打乱段内布局。核心原因:汇编器会将同一代码段(默认是
.text段)内的符号按编写顺序放入目标文件的对应段中,链接器处理相同段的内容时,会按目标文件的原有顺序合并,除非通过链接脚本指定了特殊的段排序规则。function_foo和function_foo_end属于同一个.text段,且在汇编代码里连续定义,链接后它们在内存中必然保持连续,且function_foo_end的地址一定大于function_foo的地址。额外优化建议:如果想要更稳妥,可以用汇编的
.size伪指令显式声明函数大小,比如在汇编代码里添加:.size function_foo, function_foo_end - function_foo这样不仅能让
nm、objdump等工具正确识别函数大小,也能在一定程度上避免链接时的意外调整(不过常规情况下不加也能正常工作)。
内容的提问来源于stack exchange,提问作者ackerleytng
相关产品推荐
相关产品推荐

