Le noyau Linux peut charger plusieurs formats binaires différents - ELF est simplement le plus courant, bien que le format a.out soit également assez bien connu.
Les formats binaires pris en charge sont contrôlés par les modules binfmt chargés ou compilés dans le noyau (ils se trouvent dans la section Filesystem de la configuration du noyau). Il y a un binfmt_flat
pour les binaires au format plat uClinux BFLT qui sont assez minimes - ils peuvent même être compressés en zlib, ce qui vous permettra de rendre votre binaire encore plus petit, donc cela pourrait être un bon choix.
Il ne semble pas que nasm supporte nativement ce format, mais il est assez facile d'ajouter manuellement l'en-tête nécessaire comme Jim Lewis le décrit pour ELF. Il y a une description du format ici.
Y a-t-il une raison pour laquelle vous ne voulez pas utiliser "-f elf" au lieu de "-f bin" ?
Je pense que Linux n'exécutera pas un binaire qui n'est pas au format ELF. Je ne trouve pas d'outil qui convertit les binaires plats en ELF, mais vous pouvez tricher en mettant les informations ELF dans foo.asm, en utilisant la technique décrite ici :
Nous pouvons regarder la spécification ELF, et /usr/include/linux/elf.h, et les exécutables créés par les outils standard, pour comprendre à quoi devrait ressembler notre exécutable videELF. Mais, si vous êtes du genre impatient, vous pouvez simplement utiliser celui que j'ai fourni ici :
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 $ - $$
Cette image contient un en-tête ELF, identifiant le fichier comme un exécutable Intel 386, sans table d'en-tête de section et une table d'en-tête de programme contenant une entrée. Cette entrée demande au chargeur de programme de charger le fichier entier en mémoire (il est normal qu'un programme inclue son en-tête ELF et sa table d'en-tête de programme dans son image mémoire) en commençant à l'adresse mémoire 0x08048000 (qui est l'adresse par défaut pour les exécutables à charger), et de commencer l'exécution le code à _start, qui apparaît immédiatement après la table d'en-tête de programme. Pas de segment .data, pas de segment .bss, pas de commentaire - rien que le strict nécessaire.
Alors, ajoutons dans notre petit programme :
; tiny.asm org 0x08048000 ; ; (as above) ; _start: mov bl, 42 xor eax, eax inc eax int 0x80 filesize equ $ - $$
et essayez-le :
$ nasm -f bin -o a.out tiny.asm $ chmod +x a.out $ ./a.out ; echo $? 42