Der Linux-Kernel kann mehrere verschiedene Binärformate laden - ELF ist nur das gebräuchlichste, obwohl das a.out-Format auch ziemlich bekannt ist.
Die unterstützten Binärformate werden dadurch gesteuert, welche binfmt-Module geladen oder in den Kernel kompiliert werden (sie befinden sich im Abschnitt Filesystem der Kernel-Konfiguration). Da ist ein binfmt_flat
für uClinux BFLT-Flat-Format-Binärdateien, die ziemlich minimal sind - sie können sogar zlib-komprimiert werden, wodurch Sie Ihre Binärdatei noch kleiner machen können, also könnte dies eine gute Wahl sein.
Es sieht nicht so aus, als ob Nasm dieses Format nativ unterstützt, aber es ist ziemlich einfach, den erforderlichen Header manuell hinzuzufügen, wie Jim Lewis es für ELF beschreibt. Eine Beschreibung des Formats finden Sie hier.
Gibt es einen Grund, warum Sie nicht "-f elf" anstelle von "-f bin" verwenden möchten?
Ich denke, Linux wird keine Binärdatei ausführen, die nicht im ELF-Format vorliegt. Ich kann kein Tool finden, das flache Binärdateien in ELF konvertiert, aber Sie können schummeln, indem Sie die ELF-Informationen in foo.asm einfügen, indem Sie die hier beschriebene Technik verwenden:
Wir können uns die ELF-Spezifikation und /usr/include/linux/elf.h sowie von den Standardtools erstellte ausführbare Dateien ansehen, um herauszufinden, wie unsere ausführbare leere ELF-Datei aussehen sollte. Aber, wenn Sie der ungeduldige Typ sind, können Sie einfach den verwenden, den ich hier bereitgestellt habe:
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 $ - $$
Dieses Bild enthält einen ELF-Header, der die Datei als ausführbare Intel 386-Datei identifiziert, ohne Abschnitts-Header-Tabelle und eine Programm-Header-Tabelle mit einem Eintrag. Dieser Eintrag weist den Programmlader an, die gesamte Datei in den Speicher zu laden (es ist ein normales Verhalten für ein Programm, seinen ELF-Header und seine Programmheader-Tabelle in sein Speicherabbild aufzunehmen), beginnend bei der Speicheradresse 0x08048000 (das ist die Standardadresse für zu ladende ausführbare Dateien) und mit der Ausführung zu beginnen der Code bei _start, der unmittelbar nach der Programmkopftabelle erscheint. Kein .data-Segment, kein .bss-Segment, kein Kommentar – nichts als das Nötigste.
Fügen wir also unser kleines Programm hinzu:
; tiny.asm
org 0x08048000
;
; (as above)
;
_start: mov bl, 42 xor eax, eax inc eax int 0x80 filesize equ $ - $$
und probiere es aus:
$ nasm -f bin -o a.out tiny.asm
$ chmod +x a.out
$ ./a.out ; echo $?
42