为什么我必须使用 ld 来 link 我的二进制文件
Why do I have to use ld to link my binary
我正在 Ubuntu 机器上 NASM 到 运行 中做一个 "Hello World" 小程序(uname -a 输出包含在下面):
$uname -a
Linux desk069 4.15.0-66-generic #75-Ubuntu SMP Tue Oct 1 05:24:09 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
现在将其保存到文件后,我必须 运行
nasm -f elf64 ./test. ./test.nasm -o test.o
ld -o test test.o -m elf_x86_64
为了让我的代码正常工作。尝试 运行 test.o
给我
bash: ./test.o: cannot execute binary file: Exec format error
并尝试让 NASM 生成一个 bin 文件给了我:
$nasm -f bin ./test.nasm -o test.bin
$chmod +x ./test.bin
$./test.bin
bash: ./test.bin: cannot execute binary file: Exec format error
我的问题是,我没有使用任何库。为什么我必须使用链接器 ld? bin文件到底有什么问题?我可以做点什么让 运行 没有 ld
吗?
我的代码包含在下面。
section .text
global _start
section .data
msg db 'Hello, world!', 0xa
len equ $- msg
section .text
_start:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
Why do I have to use the linker ld?
您不一定要使用 ld
,但使用它比不用它要容易得多(见下文)。
What exactly is wrong with the bin file?
.bin
文件中没有任何内容告诉 OS 如何 加载和 运行 它。
OS 应该将这个文件映射到内存中的什么地址?它应该在哪里设置 RIP
寄存器以开始执行它?
当您在 "bare metal" 系统上创建将 运行 的程序时,您可以安排将该程序加载到处理器重置地址,处理器将开始获取并执行上电时来自该地址的指令。
但您并没有尝试这样做——您正在使用 Linux,并且需要告诉它加载程序的位置以及如何启动它。
通常此信息由 ELF
文件 header 和程序 headers(链接器准备)提供,尽管 Linux 可以执行其他文件格式嗯。
Can I do something to make it run without ld?
当然可以。您可以提供所有 ELF
header 和程序 header 位 而无需 涉及链接器。 Example。只是更难正确地做,并在出现问题时进行调试。
我正在 Ubuntu 机器上 NASM 到 运行 中做一个 "Hello World" 小程序(uname -a 输出包含在下面):
$uname -a
Linux desk069 4.15.0-66-generic #75-Ubuntu SMP Tue Oct 1 05:24:09 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
现在将其保存到文件后,我必须 运行
nasm -f elf64 ./test. ./test.nasm -o test.o
ld -o test test.o -m elf_x86_64
为了让我的代码正常工作。尝试 运行 test.o
给我
bash: ./test.o: cannot execute binary file: Exec format error
并尝试让 NASM 生成一个 bin 文件给了我:
$nasm -f bin ./test.nasm -o test.bin
$chmod +x ./test.bin
$./test.bin
bash: ./test.bin: cannot execute binary file: Exec format error
我的问题是,我没有使用任何库。为什么我必须使用链接器 ld? bin文件到底有什么问题?我可以做点什么让 运行 没有 ld
吗?
我的代码包含在下面。
section .text
global _start
section .data
msg db 'Hello, world!', 0xa
len equ $- msg
section .text
_start:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
Why do I have to use the linker ld?
您不一定要使用 ld
,但使用它比不用它要容易得多(见下文)。
What exactly is wrong with the bin file?
.bin
文件中没有任何内容告诉 OS 如何 加载和 运行 它。
OS 应该将这个文件映射到内存中的什么地址?它应该在哪里设置 RIP
寄存器以开始执行它?
当您在 "bare metal" 系统上创建将 运行 的程序时,您可以安排将该程序加载到处理器重置地址,处理器将开始获取并执行上电时来自该地址的指令。
但您并没有尝试这样做——您正在使用 Linux,并且需要告诉它加载程序的位置以及如何启动它。
通常此信息由 ELF
文件 header 和程序 headers(链接器准备)提供,尽管 Linux 可以执行其他文件格式嗯。
Can I do something to make it run without ld?
当然可以。您可以提供所有 ELF
header 和程序 header 位 而无需 涉及链接器。 Example。只是更难正确地做,并在出现问题时进行调试。