.text # section declaration # we must export the entry point to the ELF linker or loader. # They convientionally recognize _start as their entry point. # Use ld -e main to override the default if you wish .global _start hex: # Purge Comment Lines cmp $35, %rax je purge_comment # deal all ascii less than 0 cmp $48, %rax jl ascii_other # deal with 0-9 cmp $58, %rax jl ascii_num # deal with all ascii less than A cmp $65, %rax jl ascii_other # deal with A-F cmp $71, %rax jl ascii_high #deal with all ascii less than a cmp $97, %rax jl ascii_other #deal with a-f cmp $103, %rax jl ascii_low # The rest that remains needs to be ignored jmp ascii_other purge_comment: # Attempt to read 1 byte from STDIN mov $1, %rdx # set the size of chars we want mov $input, %rsi # Where to put it mov $0, %rdi # Where are we reading from mov $0, %rax # the syscall number for read syscall # call the Kernel test %rax, %rax # check what we got jz Done # Got EOF call it done # load byte movb input, %al # load char movzx %al, %rax # We have to zero extend it to use it # Loop if not LF cmp $10, %rax jne purge_comment # Otherwise return -1 mov $-1, %rax ret ascii_num: sub $48, %rax ret ascii_low: sub $87, %rax ret ascii_high: sub $55, %rax ret ascii_other: mov $-1, %rax ret _start: # Our flag for byte processing mov $-1, %r15 # temp storage for the sum mov $0, %r14 loop: # Attempt to read 1 byte from STDIN mov $1, %rdx # set the size of chars we want mov $input, %rsi # Where to put it mov $0, %rdi # Where are we reading from mov $0, %rax # the syscall number for read syscall # call the Kernel test %rax, %rax # check what we got jz Done # Got EOF call it done # load byte movb input, %al # load char movzx %al, %rax # We have to zero extend it to use it # process byte call hex # deal with -1 values cmp $0, %rax jl loop # deal with toggle cmp $0, %r15 jge print # process first byte of pair mov %rax, %r14 mov $0, %r15 jmp loop # process second byte of pair print: # update the sum and store in output shl $4, %r14 add %r14, %rax mov %al, output # flip the toggle mov $-1, %r15 # Print our first Hex mov $1, %rdx # set the size of chars we want mov $output, %rsi # What we are writing mov $1, %rdi # Stdout File Descriptor mov $1, %rax # the syscall number for write syscall # call the Kernel jmp loop Done: # program completed Successfully mov $0, %rdi # All is well mov $60, %rax # put the exit syscall number in eax syscall # Call it a good day # Our writable space .data read_size = 2 input: .byte read_size output: .byte 0x00