hex.M1 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. ## Copyright (C) 2017 Jeremiah Orians
  2. ## This file is part of stage0.
  3. ##
  4. ## stage0 is free software: you can redistribute it and/or modify
  5. ## it under the terms of the GNU General Public License as published by
  6. ## the Free Software Foundation, either version 3 of the License, or
  7. ## (at your option) any later version.
  8. ##
  9. ## stage0 is distributed in the hope that it will be useful,
  10. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ## GNU General Public License for more details.
  13. ##
  14. ## You should have received a copy of the GNU General Public License
  15. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
  16. DEFINE ADD_ebp_TO_eax 01E8
  17. DEFINE CALLI32 E8
  18. DEFINE CMP_eax_Immediate8 83F8
  19. DEFINE CMP_edi_Immediate8 83FF
  20. DEFINE INT_80 CD80
  21. DEFINE JE32 0F84
  22. DEFINE JE8 74
  23. DEFINE JGE8 7D
  24. DEFINE JL8 7C
  25. DEFINE JMP32 E9
  26. DEFINE JMP8 EB
  27. DEFINE LOAD32I_eax B8
  28. DEFINE LOAD32I_ebp BD
  29. DEFINE LOAD32I_ebx BB
  30. DEFINE LOAD32I_ecx B9
  31. DEFINE LOAD32I_edi BF
  32. DEFINE LOAD32I_edx BA
  33. DEFINE LOAD8_al_Absolute32 A0
  34. DEFINE MOVE_eax_TO_ebp 89C5
  35. DEFINE MOVZBL_eax_al 0FB6C0
  36. DEFINE NULL 00000000
  37. DEFINE RET C3
  38. DEFINE SHL_ebp_Immediate8 C1E5
  39. DEFINE STORE8_al_Absolute32 A2
  40. DEFINE SUB_eax_Immediate8 83E8
  41. DEFINE TEST_eax_eax 85C0
  42. # Where the ELF Header is going to hit
  43. # Simply jump to _start
  44. JMP32 %_start
  45. :read_byte
  46. # Attempt to read 1 byte from STDIN
  47. LOAD32I_edx %1 # set the size of chars we want
  48. LOAD32I_ecx &input # Where to put it
  49. LOAD32I_ebx %0 # Where are we reading from
  50. LOAD32I_eax %3 # the syscall number for read
  51. INT_80 # call the Kernel
  52. TEST_eax_eax # check what we got
  53. JE32 %Done # Got EOF call it done
  54. # load byte
  55. LOAD8_al_Absolute32 &input # load char
  56. MOVZBL_eax_al # We have to zero extend it to use it
  57. RET
  58. :print_byte
  59. # Print our first Hex
  60. LOAD32I_edx %1 # set the size of chars we want
  61. LOAD32I_ecx &output # What we are writing
  62. LOAD32I_ebx %1 # Stdout File Descriptor
  63. LOAD32I_eax %4 # the syscall number for write
  64. INT_80 # call the Kernel
  65. :hex
  66. # Deal with #
  67. CMP_eax_Immediate8 !35
  68. JE8 !ascii_comment
  69. # deal with ;
  70. CMP_eax_Immediate8 !59
  71. JE8 !ascii_comment
  72. # deal all ascii less than 0
  73. CMP_eax_Immediate8 !48
  74. JL8 !ascii_other
  75. # deal with 0-9
  76. CMP_eax_Immediate8 !58
  77. JL8 !ascii_num
  78. # deal with all ascii less than A
  79. CMP_eax_Immediate8 !65
  80. JL8 !ascii_other
  81. # deal with A-F
  82. CMP_eax_Immediate8 !71
  83. JL8 !ascii_high
  84. #deal with all ascii less than a
  85. CMP_eax_Immediate8 !97
  86. JL8 !ascii_other
  87. #deal with a-f
  88. CMP_eax_Immediate8 !103
  89. JL8 !ascii_low
  90. # The rest that remains needs to be ignored
  91. JMP8 !ascii_other
  92. :ascii_num
  93. SUB_eax_Immediate8 !48
  94. RET
  95. :ascii_low
  96. SUB_eax_Immediate8 !87
  97. RET
  98. :ascii_high
  99. SUB_eax_Immediate8 !55
  100. RET
  101. :ascii_other
  102. LOAD32I_eax %-1
  103. RET
  104. :ascii_comment
  105. CALLI32 %read_byte
  106. CMP_eax_Immediate8 !10
  107. JE8 !ascii_other
  108. JMP8 !ascii_comment
  109. :_start
  110. # Our flag for byte processing
  111. LOAD32I_edi %-1
  112. # temp storage for the sum
  113. LOAD32I_ebp %0
  114. :loop
  115. # Read in a byte
  116. CALLI32 %read_byte
  117. # process byte
  118. CALLI32 %hex
  119. # deal with -1 values
  120. CMP_eax_Immediate8 !0
  121. JL8 !loop
  122. # deal with toggle
  123. CMP_edi_Immediate8 !0
  124. JGE8 !print
  125. # process first byte of pair
  126. MOVE_eax_TO_ebp
  127. LOAD32I_edi %0
  128. JMP8 !loop
  129. # process second byte of pair
  130. :print
  131. # update the sum and store in output
  132. SHL_ebp_Immediate8 !4
  133. ADD_ebp_TO_eax
  134. STORE8_al_Absolute32 &output
  135. # flip the toggle
  136. LOAD32I_edi %-1
  137. CALLI32 %print_byte
  138. JMP8 !loop
  139. :Done
  140. # program completed Successfully
  141. LOAD32I_ebx %0 # All is well
  142. LOAD32I_eax %1 # put the exit syscall number in eax
  143. INT_80 # Call it a good day
  144. # Our writable space
  145. :input
  146. NULL
  147. :output
  148. NULL
  149. :ELF_end