x64架构下下述汇编代码为何在Linux Ubuntu 17.x触发段错误?
问题分析与解决
首先咱们来拆解这个跨平台汇编的问题:你的代码在Mac上能正常运行,但在Ubuntu 17.x触发段错误,核心原因是Linux ELF和Mac Mach-O对符号可见性的处理逻辑存在差异。
问题根源
你定义的entry_point是一个局部符号(没有添加.global声明):
entry_point: pushq %rbp movq %rsp, %rbp popq %rbp ret
在Mac的Mach-O环境下,同一.text段内的局部符号调用可以被正确解析;但在Linux的ELF链接器规则里,未声明为全局的符号可能会被优化掉,或者调用时无法正确定位到该符号的地址,导致call entry_point跳转到无效内存地址,触发SIGSEGV段错误。
修复方案
给entry_point加上全局符号声明,让链接器明确保留这个符号:
.data .text .global entry_point ; 添加这一行全局声明 entry_point: pushq %rbp movq %rsp, %rbp popq %rbp ret .global _main _main: pushq %rbp movq %rsp, %rbp call entry_point popq %rbp ret
另外补充一点:Linux下程序的默认入口点是_start,不过如果你是用GCC编译(比如gcc your_code.s -o program),GCC会自动处理_main到_start的衔接逻辑,所以这不是当前段错误的直接原因,重点还是符号可见性的问题。
验证方法
修改后重新编译运行:
gcc your_assembly.s -o test_program ./test_program
此时应该不会再触发段错误,用GDB/LLDB调试也能正确追踪到entry_point的调用栈了。
内容的提问来源于stack exchange,提问作者flooblebit
相关产品推荐
相关产品推荐

