Linux カーネルは、いくつかの異なるバイナリ形式をロードできます。a.out 形式もよく知られていますが、ELF が最も一般的です。
サポートされているバイナリ形式は、どの binfmt モジュールがカーネルにロードまたはコンパイルされるかによって制御されます (これらはカーネル構成のファイルシステム セクションにあります)。 binfmt_flat
があります 非常に最小限の uClinux BFLT フラット フォーマット バイナリの場合 - zlib で圧縮することもできるため、バイナリをさらに小さくすることができるため、これは良い選択です。
nasm がこの形式をネイティブにサポートしているようには見えませんが、Jim Lewis が ELF について説明しているように、必要なヘッダーを手動で追加するのは非常に簡単です。ここにフォーマットの説明があります。
「-f bin」の代わりに「-f elf」を使用したくない理由はありますか?
Linux は、ELF 形式ではないバイナリを実行しないと思います。フラット バイナリを ELF に変換するツールは見つかりませんが、ここで説明する手法を使用して ELF 情報を foo.asm に入れることでごまかすことができます:
<ブロック引用>ELF 仕様、/usr/include/linux/elf.h、および標準ツールによって作成された実行可能ファイルを見て、空の ELF 実行可能ファイルがどのように見えるかを判断できます。ただし、せっかちなタイプの場合は、ここで提供したものを使用できます:
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 $ - $$
このイメージには ELF ヘッダーが含まれており、ファイルが Intel 386 実行可能ファイルであることを示しています。セクション ヘッダー テーブルはなく、プログラム ヘッダー テーブルには 1 つのエントリが含まれています。このエントリは、メモリ アドレス 0x08048000 (ロードする実行可能ファイルのデフォルト アドレス) から開始して、ファイル全体をメモリにロードするようにプログラム ローダーに指示します (プログラムがそのメモリ イメージに ELF ヘッダーとプログラム ヘッダー テーブルを含めるのは通常の動作です)。 programheader テーブルの直後にある _start のコード。 .data セグメントも .bss セグメントもコメントもありません — 必要最低限のものしかありません。
それでは、小さなプログラムを追加しましょう:
; tiny.asm
org 0x08048000
;
; (as above)
;
_start: mov bl, 42 xor eax, eax inc eax int 0x80 filesize equ $ - $$
試してみてください:
$ nasm -f bin -o a.out tiny.asm
$ chmod +x a.out
$ ./a.out ; echo $?
42