x86汇编生成的helloworld.o目标文件链接时究竟依赖什么?
x86汇编程序链接时的实际行为
先贴出你写的NASM代码:
global _start section .text: _start: mov eax, 4 mov ebx, 1 mov ecx, msg mov edx, msglen int 0x80 mov eax, 1 mov ebx, 0 int 0x80 section .data: msg: db "Hello World!", 0x0A msglen equ $-msg
当你执行ld -m elf_i386 helloworld.o时,这个过程完全没有链接任何外部库,链接器ld只是在做最基础的目标文件转可执行文件的工作,具体包括:
- 将目标文件里的
.text(代码段)、.data(数据段)合并到ELF可执行文件的对应内存区域 - 解析并填充代码里的内部符号引用:比如
msg、msglen这些你定义的符号,链接器会把它们的实际内存地址填入对应的指令中 - 设置可执行文件的入口点为
_start——这是Linux下ld默认的程序入口符号,内核加载可执行文件后会从这个地址开始执行
和C程序链接的区别
C程序默认链接libc(C标准库),原因有两个:
- 绝大多数C代码会调用
printf、malloc、exit这些libc提供的函数,必须依赖库文件才能找到这些函数的实现 - C程序的入口不是你写的
main——链接器会自动链接crt0.o这类启动代码,它负责初始化libc的运行环境(比如堆、全局变量初始化),然后调用你的main函数,最后通过exit系统调用终止程序
而你的汇编程序直接通过int 0x80触发Linux系统调用,所有功能都是直接和内核交互实现的,没有依赖任何外部库的函数或启动代码,所以链接器只需要把你的代码和数据打包成内核能识别的可执行格式就行,不需要额外链接任何库。
内容的提问来源于stack exchange,提问作者First User
相关产品推荐
相关产品推荐

