Kernel Linux dapat memuat beberapa format biner yang berbeda - ELF hanyalah yang paling umum, meskipun format a.out juga cukup terkenal.
Format biner yang didukung dikendalikan oleh modul binfmt mana yang dimuat atau dikompilasi ke dalam kernel (mereka berada di bawah bagian Filesystem dari konfigurasi kernel). Ada binfmt_flat
untuk binari format datar uClinux BFLT yang sangat minim - binari tersebut bahkan dapat dikompresi zlib yang memungkinkan Anda menjadikan biner Anda lebih kecil, jadi ini bisa menjadi pilihan yang baik.
Sepertinya nasm tidak mendukung format ini secara native, tetapi cukup mudah untuk menambahkan header yang diperlukan secara manual seperti yang dijelaskan Jim Lewis untuk ELF. Ada deskripsi formatnya di sini.
Apakah ada alasan mengapa Anda tidak ingin menggunakan "-f elf" alih-alih "-f bin"?
Saya pikir Linux tidak akan menjalankan biner yang tidak dalam format ELF. Saya tidak dapat menemukan alat yang mengubah binari datar menjadi ELF, tetapi Anda dapat menipu dengan meletakkan informasi ELF di foo.asm, menggunakan teknik yang dijelaskan di sini :
Kita dapat melihat spesifikasi ELF, dan/usr/include/linux/elf.h, dan executable yang dibuat oleh alat standar, untuk mencari tahu seperti apa tampilan executable ELF kosong kita. Namun, jika Anda adalah tipe orang yang tidak sabar, Anda dapat menggunakan salah satu yang telah saya sediakan di sini:
BITS 32 org 0x08048000 ehdr: ; Elf32_Ehdr db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident times 8 db 0 dw 2 ; e_type dw 3 ; e_machine dd 1 ; e_version dd _start ; e_entry dd phdr - $$ ; e_phoff dd 0 ; e_shoff dd 0 ; e_flags dw ehdrsize ; e_ehsize dw phdrsize ; e_phentsize dw 1 ; e_phnum dw 0 ; e_shentsize dw 0 ; e_shnum dw 0 ; e_shstrndx ehdrsize equ $ - ehdr phdr: ; Elf32_Phdr dd 1 ; p_type dd 0 ; p_offset dd $$ ; p_vaddr dd $$ ; p_paddr dd filesize ; p_filesz dd filesize ; p_memsz dd 5 ; p_flags dd 0x1000 ; p_align phdrsize equ $ - phdr _start: ; your program here filesize equ $ - $$
Gambar ini berisi header ELF, yang mengidentifikasi file sebagai Intel 386 yang dapat dieksekusi, tanpa tabel header bagian dan tabel header program yang berisi satu entri. Entri tersebut menginstruksikan pemuat program untuk memuat seluruh file ke dalam memori (perilaku normal bagi suatu program untuk menyertakan header ELF dan tabel header program dalam gambar memorinya) mulai dari alamat memori 0x08048000 (yang merupakan alamat default untuk memuat file yang dapat dieksekusi), dan untuk mulai mengeksekusi kode di _start, yang muncul tepat setelah tabel header program. Tidak ada segmen .data, segmen no.bss, tidak ada komentar — hanya kebutuhan dasar.
Jadi, mari tambahkan program kecil kita:
; tiny.asm org 0x08048000 ; ; (as above) ; _start: mov bl, 42 xor eax, eax inc eax int 0x80 filesize equ $ - $$
dan mencobanya:
$ nasm -f bin -o a.out tiny.asm $ chmod +x a.out $ ./a.out ; echo $? 42