;; Copyright (C) 2017 Jeremiah Orians ;; This file is part of stage0. ;; ;; stage0 is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; ;; stage0 is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with stage0. If not, see . section .text global _start ; Where the ELF Header is going to hit ; Simply jump to _start ; Our main function _start: pop rax ;·Get·the·number·of·arguments pop rdi ;·Get·the·program·name pop rdi ;·Get·the·actual·input name mov rsi, 0 ;·prepare·read_only mov rax, 2 ;·the·syscall·number·for·open() syscall ; Now open that damn file mov r9, rax ; Preserve the file pointer we were given pop rdi ;·Get·the·actual·output name mov rsi, 577 ; Prepare file as O_WRONLY|O_CREAT|O_TRUNC mov rdx, 448 ; Prepare file as RWX for owner only (700 in octal) mov rax, 2 ;·the·syscall·number·for·open() syscall ; Now open that damn file mov r10, rax ; Preserve the file pointer we were given ; Our flag for byte processing mov r15, -1 ; temp storage for the sum mov r14, 0 loop: ; Read a byte call Read_byte ; process byte call hex ; Deal with -1 values cmp rax, 0 jl loop ; deal with toggle cmp r15, 0 jge print ; process first byte of pair mov r14, rax mov r15, 0 jmp loop ; process second byte of pair print: ; update the sum and store in output shl r14, 4 add rax, r14 mov [output], al ; flip the toggle mov r15, -1 call write_byte jmp loop hex: ; Purge Comment Lines (#) cmp rax, 35 je purge_comment ; Purge Comment Lines (;) cmp rax, 59 je purge_comment ; deal all ascii less than 0 cmp rax, 48 jl ascii_other ; deal with 0-9 cmp rax, 58 jl ascii_num ; deal with all ascii less than A cmp rax, 65 jl ascii_other ; deal with A-F cmp rax, 71 jl ascii_high ;deal with all ascii less than a cmp rax, 97 jl ascii_other ;deal with a-f cmp rax, 103 jl ascii_low ; The rest that remains needs to be ignored jmp ascii_other purge_comment: ; Read a byte call Read_byte ; Loop if not LF cmp rax, 10 jne purge_comment ; Otherwise return -1 mov rax, -1 ret ascii_num: sub rax, 48 ret ascii_low: sub rax, 87 ret ascii_high: sub rax, 55 ret ascii_other: mov rax, -1 ret Done: ; program completed Successfully mov rdi, 0 ; All is well mov rax, 60 ; put the exit syscall number in eax syscall ; Call it a good day write_byte: ; Print our Hex mov rdx, 1 ; set the size of chars we want mov rsi, output ; What we are writing mov rdi, r10 ; Where are we writing to mov rax, 1 ; the syscall number for write syscall ; call the Kernel ret Read_byte: ; Attempt to read 1 byte from STDIN mov rdx, 1 ; set the size of chars we want mov rsi, input ; Where to put it mov rdi, r9 ; Where are we reading from mov rax, 0 ; the syscall number for read syscall ; call the Kernel test rax, rax ; check what we got je Done ; Got EOF call it done ; load byte mov al, [input] ; load char movzx rax, al ; We have to zero extend it to use it ret section .data ELF_end: ; Where we are putting our output output: ; Reserve 4bytes of Zeros dq 0 ; Where we get our input input: ; Reserve 4bytes of Zeros dq 0