# >>>>>>>>>>>>> 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
82 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
00 00 00 00 # 3C p_offset: file offset where segment begins
00 80 04 08 # 40 p_vaddr: virtual address of segment in memory (x86: 08048000)
00 00 00 00 # 44 p_paddr: physical address of segment, unspecified by 386 supplement
15 01 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 <<<<<<<<<<<<<
#### LIBRARY ####
# INTENTION INSTRUCTION OPCODE NOTE
# PutOut: # ECX=obuf EDX=count 54 -- <0:err =0:ok EAX=stat ECX=? EDX=? EBX=1
31 DB 43 # ebx = 1 (stdout) xor r/m32, r32; inc 31 /r 11 011 011
# .flush: # 57
8D 43 03 # eax = ebx + 3 (write) lea r32, m 8D /r 01 000 011
CD 80 # syscall int imm8 CD ib
85 C0 # cmp eax, 0 test r/m32, r32 85 /r 11 000 000
7C 06 # jump .ret if < 60 jl rel8 7C cb
01 C1 # ecx += eax add r/m32, r32 01 /r 11 000 001
29 C2 # edx -= eax sub r/m32, r32 29 /r 11 000 010
7F F1 # jump .flush if > 66 jg rel8 7F cb
# .ret: 66
C3 # return ret C3
# To use input, reserve ESI and EBP. Set EBP=0 before first use. Byte -> [ESI], each call.
# TakeIn: # ECX=ibuf EDX=count 67 -- <0:err =0:done >0:ok EAX=? EBX=0(if err)
46 # esi++ inc r32 40+rd
4D # ebp-- dec r32 48+rd
7F 0D # jump .ret if > 6B jg rel8 7F cb
31 DB # ebx = 0 (stdin) xor r/m32, r32 31 /r 11 011 011
8D 43 03 # eax = 3 (read) lea r32, m 8D /r 01 000 011
CD 80 # syscall int imm8 CD ib
85 C0 # cmp eax, 0 test r/m32, r32 85 /r 11 000 000
89 CE # esi = ecx mov r/m32, r32 89 /r 11 001 110
89 C5 # ebp = eax mov r/m32, r32 89 /r 11 000 101
# .ret: 78
C3 # return ret C3
# Exit-1: 79
4B # ebx-- dec r32 48+rd
# Exit: # EBX=stat -- 7A
31 C0 40 # eax = 1 (exit) xor r/m32, r32; inc 31 /r 11 000 000
CD 80 # syscall int imm8 CD ib
# Exit+1: 7F
43 # ebx++ inc r32 40+rd
EB F8 # jump Exit 82 jmp rel8 EB cb
# 08048000 = Head
# ecx: 20000000 = ibuf = ilen
# 40000000 = obuf = olen
# 80000000 > seg
# al: char
# ebx: acc
# ebp: num chars available in ibuf
# esi: input pointer (address in memory)
# edi: output pointer (file pos from 0)
#### COMPILER ###
# CopyHeader: # 82 <-- Entry point for this and compiled programs
31 ED # ebp = 0 xor r/m32, r32 31 /r 11 101 101
31 C9 # ecx = 0 xor r/m32, r32 31 /r 11 001 001
B1 82 # ecx = len (header) mov r8, imm8 B0+rb ib
BE 00 80 04 08 # esi = Head mov r32, imm32 B8+rd id
BF 00 00 00 20 # edi = ibuf mov r32, imm32 B8+rd id
51 57 # push ecx, edi push r32 50+rd S: len ibuf
01 FF # edi = obuf (=edi+edi) add r/m32, r32 01 /r 11 111 111
F3 A4 # copy string rep movs m8, m8 F3 A4
59 5F # ecx = ibuf, edi = len pop r32 58+rd S:
EB 24 # jump Record 9C jmp rel8 EB cb
# GetByte: # ECX=ibuf -- 9C
53 # push ebx push r32 50+rd S: acc
89 CA # edx = ecx mov r/m32, r32 89 /r 11 001 010
E8 C3 FF FF FF # call TakeIn A4 call rel32 E8 cb
7C D3 # jump Exit+1 if < A6 jl rel8 7C cb
5B # pop ebx pop r32 58+rd S:
7E 03 # jump Finish if <= A9 jle rel8 7E cb
8A 06 # al = [esi] mov r8, r/m8 8A /r 00 000 110
C3 # return ret C3
# Finish: # ECX=ibuf AC
01 C9 # ecx = obuf (=ecx+ecx) add r/m32, r32 01 /r 11 001 001
8B 51 44 # edx = [ecx+44] mov r32, r/m32 8B /r 01 010 001
E8 9E FF FF FF # call PutOut B6 call rel32 E8 cb
7C C7 # jump Exit+1 if < B8 jl rel8 7C cb
EB BF # jump Exit-1 BA jmp rel8 EB cb
# WORD: BA
39 7C 09 44 # cmp [2*ecx+44], edi cmp r/m32, r32 39 /r 01 111 100 00 001 001
7D 04 # jump Clear if >= C0 jge rel8 7D cb
# Record: C0
89 7C 09 44 # [2*ecx+44] = edi mov r/m32, r32 89 /r 01 111 100 00 001 001
# Clear: # null: 80000000 C4
6B D9 04 # ebx = ecx * 4 imul r32, r/m32, imm8 6B /r ib 11 011 001
# CHAR: C7
E8 D0 FF FF FF # call GetByte CC call rel32 E8 cd
# Hash:
3C 23 # cmp al, '#' cmp al, imm8 3C ib
7C 0B # jump WhSpace if < D0 jl rel8 7C cb
7F 13 # jump Op if > D2 jg rel8 7F cb
# Comment: D2
E8 C5 FF FF FF # call GetByte D7 call rel32 E8 cd
3C 0A # cmp al, '\n' cmp al, imm8 3C ib
75 F7 # jump Comment if != DB jne rel8 75 cb
# WhSpace: DB
85 DB # cmp ebx, 0 test r/m32, r32 85 /r 11 011 011
7C DB # jump WORD if < DF jl rel8 7C cb
88 1C 4F # [2*ecx+edi] = bl mov r/m8, r8 88 /r 00 011 100 01 001 111
47 # edi++ inc r32 40+rd
EB D5 # jump WORD E5 jmp rel8 EB cb
# Op: E5 ASCII summary: \t\n #+-0:A
3C 2D # cmp al, '-' cmp al, imm8 3C ib
74 25 # jump Minus if == E9 je rel8 74 cb
7C 15 # jump Plus if < EB jl rel8 7C cb
3C 3A # cmp al, ':'
74 0D # jump Colon if == EF je rel8 74 cb
7C 02 # jump Digit if < F1 jl rel8 7C cb
# Letter:
2C 07 # al -= 'A'-'0'-A sub al, imm8 2C ib
# Digit: F3
2C 30 # al -= '0' sub al, imm8 2C ib
C1 E3 04 # ebx <<= 4 shl r/m32, imm8 C1 /4 ib 11 100 011
00 C3 # bl += al add r/m8, r8 00 /r 11 000 011
EB CB # jump CHAR FC jmp rel8 EB cb
# Colon: FC
89 DF # edi = ebx mov r/m32, r32 89 /r 11 011 111
EB BA # jump WORD 100 jmp rel8 EB cb
# Plus: 100
81 C3 00 80 04 08 # ebx += Head add r/m32, imm32 81 /0 id 11 000 011
# Append: 106
89 1C 4F # [2*ecx+edi] = ebx mov r/m32, r32 89 /r 00 011 100 01 001 111
83 C7 04 # edi += 4 add r/m32, imm8 83 /0 ib 11 000 111
EB AC # jump WORD 10E jmp rel8 EB cb
# Minus: 10E
83 EB 04 # ebx -= 4 sub r/m32, imm8 83 /5 ib 11 101 011
29 FB # ebx -= edi sub r/m32, r32 29 /r 11 111 011
EB F1 # jump Append 115 jmp rel8 EB cb