I'm doing a little "Hello World" program in NASM to run on my Ubuntu machine (uname -a output included below):
$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
Now after saving this to a file, I have to run
nasm -f elf64 ./test. ./test.nasm -o test.o
ld -o test test.o -m elf_x86_64
In order for my code to work. Attempting to run test.o
gives me
bash: ./test.o: cannot execute binary file: Exec format error
and attempting to make NASM generate a bin file gives me:
$nasm -f bin ./test.nasm -o test.bin
$chmod +x ./test.bin
$./test.bin
bash: ./test.bin: cannot execute binary file: Exec format error
My question is, I'm not using any libraries. Why do I have to use the linker ld? What exactly is wrong with the bin file? Can I do something to make it run without ld
?
My code is included below.
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?
You don't have to use ld
, but it's much easier to use it than not (see below).
What exactly is wrong with the bin file?
Nothing in the .bin
file tells the OS how to load and run it.
At what address should the OS map this file into memory? Where should it set the RIP
register to start executing it?
When you create a program which will run on a "bare metal" system, you can arrange for this program to be loaded at exactly the processor reset address, and the processor will start fetching and executing instructions from that address when it is powered on.
But you aren't trying to do that -- you are using Linux, and it needs to be told where to load the program and how to start it.
Usually this info is supplied by the ELF
file header and program headers (which the linker prepares), although Linux can execute other file formats as well.
Can I do something to make it run without ld?
Sure. You can supply all the ELF
header and program header bits without involving a linker at all. Example. It's just much harder to do correctly, and to debug when things go wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With