boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

hex1.hex0 (10784B)


      1 # SPDX-FileCopyrightText: 2017 Jeremiah Orians <jeremiah@pdp10.guru>
      2 # SPDX-FileCopyrightText: 2023 Andrius Štikonas <andrius@stikonas.eu>
      3 #
      4 # SPDX-License-Identifier: GPL-3.0-or-later
      5 
      6 ## ELF Header
      7 #:ELF_base
      8 7F 45 4C 46        ## e_ident[EI_MAG0-3] ELF's magic number
      9 
     10 02                 ## e_ident[EI_CLASS] Indicating 64 bit
     11 01                 ## e_ident[EI_DATA] Indicating little endianness
     12 01                 ## e_ident[EI_VERSION] Indicating original elf
     13 
     14 03                 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
     15 00                 ## e_ident[EI_ABIVERSION] Set at 0 because none cares
     16 
     17 00 00 00 00 00 00 00 ## e_ident[EI_PAD]
     18 02 00              ## e_type Indicating Executable
     19 3E 00              ## e_machine Indicating AMD64
     20 01 00 00 00        ## e_version Indicating original elf
     21 
     22 78 00 60 00 00 00 00 00 ## e_entry Address of the entry point (Number of bytes this header is + Base Address)
     23 40 00 00 00 00 00 00 00 ## e_phoff Address of program header table
     24 00 00 00 00 00 00 00 00 ## e_shoff Address of section header table
     25 
     26 00 00 00 00        ## e_flags
     27 40 00              ## e_ehsize Indicating our 64 Byte header
     28 
     29 38 00              ## e_phentsize size of a program header table
     30 01 00              ## e_phnum number of entries in program table
     31 
     32 00 00              ## e_shentsize size of a section header table
     33 00 00              ## e_shnum number of entries in section table
     34 
     35 00 00              ## e_shstrndx index of the section names
     36 
     37 ## Program Header
     38 #:ELF_program_headers
     39 01 00 00 00             ## p_type
     40 07 00 00 00             ## ph_flags: PF-X|PF-W|PF-R = 7
     41 00 00 00 00 00 00 00 00 ## p_offset
     42 
     43 00 00 60 00 00 00 00 00 ## p_vaddr
     44 00 00 60 00 00 00 00 00 ## p_physaddr
     45 
     46 6E 02 00 00 00 00 00 00 ## p_filesz
     47 6E 02 00 00 00 00 00 00 ## p_memsz
     48 
     49 01 00 00 00 00 00 00 00 ## Required alignment
     50 
     51 #:ELF_text
     52 
     53 # Where the ELF Header is going to hit
     54 # Simply jump to _start
     55 # Our main function
     56 
     57 # :_start (0x600078)
     58 	58                  ; pop_rax         # Get the number of arguments
     59 	5F                  ; pop_rdi         # Get the program name$
     60 	5F                  ; pop_rdi         # Get the actual input name
     61 	48C7C6 00000000     ; mov_rsi, %0     # prepare read_only
     62 	48C7C0 02000000     ; mov_rax, %2     # the syscall number for open()
     63 	0F05                ; syscall         # Now open that damn file
     64 	4989C1              ; mov_r9,rax      # Preserve the file pointer we were given
     65 
     66 	5F                  ; pop_rdi         # Get the actual output name
     67 	48C7C6 41020000     ; mov_rsi, %577   # Prepare file as O_WRONLY|O_CREAT|O_TRUNC
     68 	48C7C2 C0010000     ; mov_rdx, %448   # Prepare file as RWX for owner only (700 in octal)
     69 	48C7C0 02000000     ; mov_rax, %2     # the syscall number for open()
     70 	0F05                ; syscall         # Now open that damn file
     71 	4989C2              ; mov_r10,rax     # Preserve the file pointer we were given
     72 
     73 	49C7C7 FFFFFFFF     ; mov_r15, %-1    # Our flag for byte processing
     74 	49C7C6 00000000     ; mov_r14, %0     # temp storage for the sum
     75 	49C7C5 00000000     ; mov_r13, %0     # Our starting IP
     76 	E8 39000000         ; call %First_pass # Process it
     77 
     78 	# rewind input file
     79 	4C89CF              ; mov_rdi,r9      # Using our input file
     80 	48C7C6 00000000     ; mov_rsi, %0     # Offset Zero
     81 	48C7C2 00000000     ; mov_rdx, %0     # Whence Zero
     82 	48C7C0 08000000     ; mov_rax, %8     # lseek
     83 	0F05                ; syscall
     84 
     85 	49C7C7 FFFFFFFF     ; mov_r15, %-1    # Our flag for byte processing
     86 	49C7C6 00000000     ; mov_r14, %0     # temp storage for the sum
     87 	49C7C5 00000000     ; mov_r13, %0     # Our starting IP
     88 	E8 69000000         ; call %Second_pass # Process it
     89 
     90 	E9 E4000000         ; jmp %Done
     91 
     92 # :First_pass (0x6000FC)
     93 	E8 EF000000         ; call %Read_byte
     94 
     95 	# Deal with EOF
     96 	3C FC               ; cmp_al, !-4
     97 	74 34               ; je8 !First_pass_done
     98 
     99 	# Check for :
    100 	3C 3A               ; cmp_al, !0x3a
    101 	75 05               ; jne8 !First_pass_0
    102 
    103 	# Deal with label
    104 	E8 32010000         ; call %StoreLabel
    105 
    106 # :First_pass_0 (0x60010E)
    107 	# Check for %
    108 	3C 25               ; cmp_al, !0x25
    109 	74 1C               ; je8 !First_pass_pointer
    110 
    111 	# Deal with everything else
    112 	E8 23000000         ; call %hex       # Process our char
    113 
    114 	# Deal with EOF
    115 	3C FC               ; cmp_al, !-4
    116 	74 1E               ; je8 !First_pass_done
    117 
    118 	# deal with -1 values
    119 	3C 00               ; cmp_al, !0
    120 	7C DD               ; jl8 !First_pass
    121 
    122 	# deal with toggle
    123 	4983FF 00           ; cmp_r15, !0
    124 	74 04               ; je8 !First_pass_1
    125 	4983C5 01           ; add_r13, !1     # Increment IP
    126 
    127 # :First_pass_1 (0x600129)
    128 	49F7D7              ; not_r15
    129 	EB CE               ; jmp8 !First_pass
    130 
    131 # :First_pass_pointer (0x60012E)
    132 	# Deal with Pointer to label
    133 	E8 BD000000         ; call %Read_byte # Drop the char
    134 	4983C5 04           ; add_r13, !4     # Increment IP
    135 	EB C3               ; jmp8 !First_pass # Loop again
    136 
    137 # :First_pass_done (0x600139)
    138 	C3                  ; ret
    139 
    140 # :hex (0x60013A)
    141 	# deal with EOF
    142 	3C FC               ; cmp_al, !-4
    143 	74 60               ; je8 !EOF
    144 	# deal with line comments starting with #
    145 	3C 23               ; cmp_al, !0x23
    146 	74 69               ; je8 !ascii_comment
    147 	# deal with line comments starting with ;
    148 	3C 3B               ; cmp_al, !0x3b
    149 	74 65               ; je8 !ascii_comment
    150 	# deal all ascii less than 0
    151 	3C 30               ; cmp_al, !0x30
    152 	7C 5E               ; jl8 !ascii_other
    153 	# deal with 0-9
    154 	3C 3A               ; cmp_al, !0x3a
    155 	7C 51               ; jl8 !ascii_num
    156 	# deal with all ascii less than A
    157 	3C 41               ; cmp_al, !0x41
    158 	7C 56               ; jl8 !ascii_other
    159 	# deal with A-F
    160 	3C 47               ; cmp_al, !0x47
    161 	7C 4F               ; jl8 !ascii_high
    162 	# deal with all ascii less than a
    163 	3C 61               ; cmp_al, !0x61
    164 	7C 4E               ; jl8 !ascii_other
    165 	# deal with a-f
    166 	3C 67               ; cmp_al, !0x67
    167 	7C 44               ; jl8 !ascii_low
    168 	# The rest that remains needs to be ignored
    169 	EB 48               ; jmp8 !ascii_other
    170 
    171 # :Second_pass (0x600160)
    172 	E8 8B000000         ; call %Read_byte
    173 
    174 	# Deal with EOF
    175 	3C FC               ; cmp_al, !-4
    176 	74 35               ; je8 !Second_pass_done
    177 
    178 	# Simply drop the label
    179 	3C 3A               ; cmp_al, !0x3a
    180 	75 07               ; jne8 !Second_pass_0
    181 
    182 	E8 7E000000         ; call %Read_byte
    183 	EB EC               ; jmp8 !Second_pass
    184 
    185 # :Second_pass_0 (0x600174)
    186 	# Deal with % pointer
    187 	3C 25               ; cmp_al, !0x25
    188 	75 07               ; jne8 !Second_pass_1
    189 
    190 	E8 CE000000         ; call %StorePointer
    191 	EB E1               ; jmp8 !Second_pass
    192 
    193 # :Second_pass_1 (0x60017F)
    194 	# Deal with everything else
    195 	E8 B6FFFFFF         ; call %hex       # Process our char
    196 
    197 	# Deal with EOF
    198 	3C FC               ; cmp_al, !-4
    199 	74 16               ; je8 !Second_pass_done
    200 
    201 	# deal with -1 values
    202 	3C 00               ; cmp_al, !0
    203 	7C D4               ; jl8 !Second_pass
    204 
    205 	# deal with toggle
    206 	4983FF 00           ; cmp_r15, !0
    207 	74 29               ; je8 !print
    208 
    209 	# process first byte of pair
    210 	4989C6              ; mov_r14,rax
    211 	49C7C7 00000000     ; mov_r15, %0
    212 	EB C2               ; jmp8 !Second_pass
    213 
    214 # :Second_pass_done (0x60019E)
    215 # :EOF
    216 	C3                  ; ret
    217 # :ascii_num (0x60019F)
    218 	2C 30               ; sub_al, !0x30
    219 	C3                  ; ret
    220 # :ascii_low (0x6001A2)
    221 	2C 57               ; sub_al, !0x57
    222 	C3                  ; ret
    223 # :ascii_high (0x6001A5)
    224 	2C 37               ; sub_al, !0x37
    225 	C3                  ; ret
    226 # :ascii_other (0x6001A8)
    227 	B0 FF               ; mov_al, !-1
    228 	C3                  ; ret
    229 # :ascii_comment (0x6001AB)
    230 	E8 40000000         ; call %Read_byte
    231 	3C 0D               ; cmp_al, !0xd
    232 	74 04               ; je8 !ascii_comment_cr
    233 	3C 0A               ; cmp_al, !0xa
    234 	75 F3               ; jne8 !ascii_comment
    235 # :ascii_comment_cr (0x6001B8)
    236 	B0 FF               ; mov_al, !-1
    237 	C3                  ; ret
    238 
    239 # process second byte of pair
    240 # :print (0x6001BB)
    241 	# update the sum and store in output
    242 	49C1E6 04           ; shl_r14, !4
    243 	4C01F0              ; add_rax,r14
    244 	8805 A6000000       ; mov_[rip+DWORD],al %table
    245 
    246 	# flip the toggle
    247 	49F7D7              ; not_r15
    248 
    249 	# Print our first Hex
    250 	48C7C2 01000000     ; mov_rdx, %1     # set the size of chars we want
    251 	E8 41000000         ; call %print_chars
    252 
    253 	4983C5 01           ; add_r13, !1     # Increment IP
    254 	E9 80FFFFFF         ; jmp %Second_pass
    255 
    256 # :Done (0x6001E0)
    257 	# program completed Successfully
    258 	48C7C7 00000000     ; mov_rdi, %0     # All is well
    259 	48C7C0 3C000000     ; mov_rax, %0x3c  # put the exit syscall number in rax
    260 	0F05                ; syscall         # Call it a good day
    261 
    262 # :Read_byte (0x6001F0)
    263 	# Attempt to read 1 byte from STDIN
    264 	48C7C2 01000000     ; mov_rdx, %1     # set the size of chars we want
    265 	488D35 70000000     ; lea_rsi,[rip+DWORD] %table # Where to put it
    266 	4C89CF              ; mov_rdi,r9      # Where are we reading from
    267 	31C0                ; xor_eax,eax     # the syscall number for read
    268 	0F05                ; syscall         # call the Kernel
    269 
    270 	4885C0              ; test_rax,rax    # check what we got
    271 	74 0B               ; je8 !Read_byte_1 # Got EOF call it done
    272 
    273 	# load byte
    274 	8A05 5E000000       ; mov_al,[rip+DWORD] %table # load char
    275 	480FB6C0            ; movzx_rax,al    # We have to zero extend it to use it
    276 	C3                  ; ret
    277 
    278 # Deal with EOF
    279 # :Read_byte_1 (0x600215)
    280 	B0 FC               ; mov_al, !-4     # Put EOF in rax
    281 	C3                  ; ret
    282 
    283 # :print_chars (0x600218)
    284 	488D35 4F000000     ; lea_rsi,[rip+DWORD] %table # What we are writing
    285 	4C89D7              ; mov_rdi,r10     # Write to target file
    286 	48C7C0 01000000     ; mov_rax, %1     # the syscall number for write
    287 	0F05                ; syscall         # call the Kernel
    288 	C3                  ; ret
    289 
    290 # :Get_table_target (0x60022C)
    291 	E8 BFFFFFFF         ; call %Read_byte # Get single char label
    292 	48C1E0 03           ; shl_rax, !3     # Each label in table takes 8 bytes to store
    293 	488D0D 32000000     ; lea_rcx,[rip+DWORD] %table # Get table
    294 	4801C8              ; add_rax,rcx     # Calculate offset
    295 	C3                  ; ret
    296 
    297 # :StoreLabel (0x600240)
    298 	E8 E7FFFFFF         ; call %Get_table_target
    299 	4C8928              ; mov_[rax],r13   # Write out pointer to table
    300 	31C0                ; xor_eax,eax     # wipe higher bits of rax, so that cmp al works
    301 	C3                  ; ret
    302 
    303 # :StorePointer (0x60024B)
    304 	4983C5 04           ; add_r13, !4     # Increment IP
    305 	E8 D8FFFFFF         ; call %Get_table_target # Get address of pointer
    306 	488B00              ; mov_rax,[rax]   # Get pointer
    307 	4C29E8              ; sub_rax,r13     # target - ip
    308 	488905 0D000000     ; mov_[rip+DWORD],rax %table # put value in output
    309 	48C7C2 04000000     ; mov_rdx, %4     # set the size of chars we want
    310 	E8 ABFFFFFF         ; call %print_chars
    311 	C3                  ; ret
    312 
    313 # :table (0x60026E)
    314 
    315 # :ELF_end