# >>>>>>>>>>>>> ELF FILE HEADER <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
# All numbers (except in names) are in base sixteen (hexadecimal)
# 00 <- number of bytes listed so far
7F 45 4C 46 # 04 e_ident[EI_MAG]: ELF magic number
01 # 05 e_ident[EI_CLASS]: 1: 32-bit, 2: 64-bit
01 # 06 e_ident[EI_DATA]: 1: little-endian, 2: big-endian
01 # 07 e_ident[EI_VERSION]: ELF header version; must be 1
00 # 08 e_ident[EI_OSABI]: Target OS ABI; should be 0
00 # 09 e_ident[EI_ABIVERSION]: ABI version; 0 is ok for Linux
00 00 00 # 0C e_ident[EI_PAD]: unused, should be 0
00 00 00 00 # 10
02 00 # 12 e_type: object file type; 2: executable
03 00 # 14 e_machine: instruction set architecture; 3: x86, 3E: amd64
01 00 00 00 # 18 e_version: ELF identification version; must be 1
54 80 04 08 # 1C e_entry: memory address of entry point (where process starts)
34 00 00 00 # 20 e_phoff: file offset where program headers begin
00 00 00 00 # 24 e_shoff: file offset where section headers begin
00 00 00 00 # 28 e_flags: 0 for x86
34 00 # 2A e_ehsize: size of this header (34: 32-bit, 40: 64-bit)
20 00 # 2C e_phentsize: size of each program header (20: 32-bit, 38: 64-bit)
01 00 # 2E e_phnum: #program headers
28 00 # 30 e_shentsize: size of each section header (28: 32-bit, 40: 64-bit)
00 00 # 32 e_shnum: #section headers
00 00 # 34 e_shstrndx: index of section header containing section names
# >>>>>>>>>>>>> ELF PROGRAM HEADER <<<<<<<<<<<<<<<<<<<<<<<<
01 00 00 00 # 38 p_type: segment type; 1: loadable
54 00 00 00 # 3C p_offset: file offset where segment begins
54 80 04 08 # 40 p_vaddr: virtual address of segment in memory (x86: 08048054)
00 00 00 00 # 44 p_paddr: physical address of segment, unspecified by 386 supplement
7D 00 00 00 # 48 p_filesz: size in bytes of the segment in the file image ############
00 80 FB 77 # 4C p_memsz: size in bytes of the segment in memory; p_filesz <= p_memsz
07 00 00 00 # 50 p_flags: segment-dependent flags (1: X, 2: W, 4: R)
00 10 00 00 # 54 p_align: 1000 for x86
# >>>>>>>>>>>>> PROGRAM SEGMENT <<<<<<<<<<<<<
# String instructions
# 08048000 Head
# 08048100 ibuf
# 08048200 obuf
# 80000000 end process segments
# INTENTION INSTRUCTION OPCODE NOTE
# Read: 54
B8 03 00 00 00 # eax = 3 (read) mov r32, imm32 B8+rd id
31 DB # ebx = 0 (stdin) xor r/m32, r32 31 /r 11 011 011
B9 00 81 04 08 # ecx = ibuf mov r32, imm32 B8+rd id
BA 00 01 00 00 # edx = count mov r32, imm32 B8+rd id
CD 80 # syscall int imm8 CD ib
# Dots: # 67
FC # forward cld FC
89 CE # esi = ecx (ibuf) mov r/m32, r32 89 /r 11 001 110
B0 2E # al = '.' mov r8, imm8 B0+rb ib
B9 20 00 00 00 # ecx = 20 mov r32, imm32 B8+rd id
BF 00 82 04 08 # edi = obuf mov r32, imm32 B8+rd id
F3 AA # write many rep stos m8 F3 AA Fill al @edi (ecx)
C6 07 0A # [edi] = '\n' mov r/m8, imm8 C6 /0 ib 00 000 111
83 EF 20 # edi -= 20 sub r/m32, imm8 83 /5 ib 11 101 111
B0 20 # al = ' ' mov r8, imm8 B0+rb ib
# esi: ibuf (input pointer)
# edi: obuf (output pointer)
# SkipSpace1: # 80
87 FE # swap esi, edi xchg r/m32, r32 87 /r 11 111 110
B1 FF # ecx = FF mov r8, imm8 B0+rb ib
F3 AE # skip while == repe scas m8 F3 AE Find non-al @edi
4F # edi-- dec r32 48+rb
87 FE # swap esi, edi xchg r/m32, r32 87 /r 11 111 110
# esi: ibuf + S01
# edi: obuf
# WordLen1: # 89
87 FE # swap esi, edi xchg r/m32, r32 87 /r 11 111 110
89 FB # ebx = edi mov r/m32, r32 89 /r 11 111 011
F2 AE # skip while != repne scas m8 F2 AE Find al @edi
4F # edi-- dec r32 48+rb
89 F9 # ecx = edi mov r/m32, r32 89 /r 11 111 001
29 D9 # ecx -= ebx sub r/m32, r32 29 /r 11 011 001
87 FE # swap esi, edi xchg r/m32, r32 87 /r 11 111 110
89 DE # esi = ebx mov r/m32, r32 89 /r 11 011 110
# ecx: T1
# esi: ibuf + S01
# edi: obuf
# CopyWord1: # 98
F3 A4 # copy rep movs m8, m8 F3 A4 esi -> edi (ecx)
# esi: ibuf + S01 + T1
# edi: obuf + T1
# SkipSpace2: # 9A
87 FE # swap esi, edi xchg r/m32, r32 87 /r 11 111 110
B1 FF # ecx = FF mov r8, imm8 B0+rb ib
F3 AE # skip while == repe scas m8 F3 AE Find non-al @edi
4F # edi-- dec r32 48+rb
87 FE # swap esi, edi xchg r/m32, r32 87 /r 11 111 110
# esi: ibuf + S01 + T1 + S12
# edi: obuf + T1
# WordLen2: # A3
87 FE # swap esi, edi xchg r/m32, r32 87 /r 11 111 110
89 FB # ebx = edi mov r/m32, r32 89 /r 11 111 011
F2 AE # skip while != repne scas m8 F2 AE Find al @edi
4F # edi-- dec r32 48+rb
89 F9 # ecx = edi mov r/m32, r32 89 /r 11 111 001
29 D9 # ecx -= ebx sub r/m32, r32 29 /r 11 011 001
87 FE # swap esi, edi xchg r/m32, r32 87 /r 11 111 110
# ecx: T2
# esi: ibuf + S01 + T1 + S12 + T2
# edi: obuf + T1
4E # esi-- dec r32 48+rd
BF 1F 82 04 08 # edi = obuf + 1F mov r32, imm32 B8+rd id
FD # backward std FD
# ecx: T2
# esi: ibuf + S01 + T1 + S12 + T2 - 1
# edi: obuf + 20 - 1
# CopyWord2: # B7
F3 A4 # copy rep movs m8, m8 F3 A4 esi -> edi (ecx)
# Write: # B9
B8 04 00 00 00 # eax = 4 (write) mov r32, imm32 B8+rd id
BB 01 00 00 00 # ebx = 1 (stdout) mov r32, imm32 B8+rd id
B9 00 82 04 08 # ecx = obuf mov r32, imm32 B8+rd id
BA 21 00 00 00 # edx = count mov r32, imm32 B8+rd id
CD 80 # syscall int imm8 CD ib
EB 83 # jump Read D1 jmp rel8 EB cb