NASM汇编代码LD链接崩溃、GCC链接正常的原因咨询
为什么自定义
_start用ld链接会崩溃,而gcc链接main正常? 1. 自定义_start崩溃的直接原因
你自己写的_start入口函数存在致命问题:程序执行完毕后没有正确终止。
看这段代码:
section .text global _start _start: enter 0, 0 call main leave ; 此处无任何退出操作!
当_start执行完leave指令后,CPU会继续执行内存中该指令之后的未定义垃圾数据,执行非法指令直接导致程序崩溃。
在x86-64 Linux环境中,_start作为程序入口,必须负责在逻辑结束后通过系统调用终止程序,否则会触发非法执行。
2. GCC提供的_start核心作用
你附上的反汇编代码是GCC自动链接的C运行时入口(来自libc),它的核心职责是:
- 完成程序初始化(栈对齐、参数整理等)
- 调用你的
main函数 - 在
main返回后自动调用exit系统调用,确保程序合法终止
关键步骤解析:
endbr64:Intel控制流强制技术的安全检查指令,防范跳转攻击xor ebp,ebp:将基址指针置0,标记栈帧底部mov r9,rdx/pop rsi:整理命令行参数(argc、argv、envp),符合C调用约定and rsp,0xfffffffffffffff0:将栈对齐到16字节(x86-64调用约定强制要求)call QWORD PTR [rip+0x2fa2]:调用__libc_start_main,该函数会负责调用main,并在main返回后触发exit系统调用
3. 修复自定义_start的方法
如果想继续用ld直接链接、不依赖C运行时,只需在_start中添加退出系统调用即可:
section .text global _start _start: enter 0, 0 call main leave ; x86-64 Linux exit系统调用(调用号60,返回码0) mov rax, 60 xor rdi, rdi syscall
添加这段代码后,程序执行完main会通过syscall合法退出,不会触发崩溃。
4. gcc链接main正常运行的原因
用gcc链接时,它会自动链接libc库,将GCC标准_start入口加入程序。这个入口会处理所有初始化和终止逻辑,包括在main返回后调用exit,因此你的main只需正常ret返回即可,无需关心退出操作。
内容的提问来源于stack exchange,提问作者Eliot Janvier
相关产品推荐
相关产品推荐

