hex.M1 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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_RAX_R14 4C01F0
  17. DEFINE CMP_RAX_Immediate8 4883F8
  18. DEFINE CMP_R15_Immediate8 4983FF
  19. DEFINE JE8 74
  20. DEFINE JNE8 75
  21. DEFINE JGE8 7D
  22. DEFINE JE32 0F84
  23. DEFINE JL8 7C
  24. DEFINE JMP8 EB
  25. DEFINE JMP32 E9
  26. DEFINE LOAD32I_RDX 48C7C2
  27. DEFINE LOAD32I_RSI 48C7C6
  28. DEFINE LOAD32I_RDI 48C7C7
  29. DEFINE LOAD32I_RAX 48C7C0
  30. DEFINE LOAD32I_R14 49C7C6
  31. DEFINE LOAD32I_R15 49C7C7
  32. DEFINE LOAD8_al_Absolute32 8A0425
  33. DEFINE STORE8_al_Absolute32 880425
  34. DEFINE SYSCALL 0F05
  35. DEFINE SHL_R14_Immediate8 49C1E6
  36. DEFINE TEST_RAX_RAX 4885C0
  37. DEFINE MOVE_R14_RAX 4989C6
  38. DEFINE MOVZBQ_RAX_AL 480FB6C0
  39. DEFINE RETQ C3
  40. DEFINE SUB_RAX_Immediate8 4883E8
  41. DEFINE CALLI32 E8
  42. DEFINE NULL 00000000
  43. # Where the ELF Header is going to hit
  44. # Simply jump to _start
  45. JMP32 %_start
  46. :hex
  47. # Purge Comment Lines (#)
  48. CMP_RAX_Immediate8 !35
  49. JE8 !purge_comment
  50. # Purge Comment Lines (;)
  51. CMP_RAX_Immediate8 !59
  52. JE8 !purge_comment
  53. # deal all ascii less than '0'
  54. CMP_RAX_Immediate8 !48
  55. JL8 !ascii_other
  56. # deal with 0-9
  57. CMP_RAX_Immediate8 !58
  58. JL8 !ascii_num
  59. # deal with all ascii less than 'A'
  60. CMP_RAX_Immediate8 !65
  61. JL8 !ascii_other
  62. # deal with 'A'-'F'
  63. CMP_RAX_Immediate8 !71
  64. JL8 !ascii_high
  65. # deal with all ascii less than 'a'
  66. CMP_RAX_Immediate8 !97
  67. JL8 !ascii_other
  68. #deal with 'a'-'f'
  69. CMP_RAX_Immediate8 !103
  70. JL8 !ascii_low
  71. # The rest that remains needs to be ignored
  72. JMP8 !ascii_other
  73. :purge_comment
  74. # Attempt to read 1 byte from STDIN
  75. LOAD32I_RDX %1 # set the size of chars we want
  76. LOAD32I_RSI &input # Where to put it
  77. LOAD32I_RDI %0 # Where are we reading from
  78. LOAD32I_RAX %0 # the syscall number for read
  79. SYSCALL # call the Kernel
  80. TEST_RAX_RAX # check what we got
  81. JE32 %Done # Got EOF call it done
  82. # load byte
  83. LOAD8_al_Absolute32 &input # load char
  84. MOVZBQ_RAX_AL # We have to zero extend it to use it
  85. # Loop if not LF
  86. CMP_RAX_Immediate8 !10
  87. JNE8 !purge_comment
  88. # Otherwise return -1
  89. LOAD32I_RAX %-1
  90. RETQ
  91. :ascii_num
  92. SUB_RAX_Immediate8 !48
  93. RETQ
  94. :ascii_low
  95. SUB_RAX_Immediate8 !87
  96. RETQ
  97. :ascii_high
  98. SUB_RAX_Immediate8 !55
  99. RETQ
  100. :ascii_other
  101. LOAD32I_RAX %-1
  102. RETQ
  103. # Our main function
  104. :_start
  105. # Our flag for byte processing
  106. LOAD32I_R15 %-1
  107. # temp storage for the sum
  108. LOAD32I_R14 %0
  109. :loop
  110. # Attempt to read 1 byte from STDIN
  111. LOAD32I_RDX %1 # set the size of chars we want
  112. LOAD32I_RSI &input # Where to put it
  113. LOAD32I_RDI %0 # Where are we reading from
  114. LOAD32I_RAX %0 # the syscall number for read
  115. SYSCALL # call the Kernel
  116. TEST_RAX_RAX # check what we got
  117. JE8 !Done # Got EOF call it done
  118. # load byte
  119. LOAD8_al_Absolute32 &input # load char
  120. MOVZBQ_RAX_AL # We have to zero extend it to use it
  121. # process byte
  122. CALLI32 %hex
  123. # deal with -1 values
  124. CMP_RAX_Immediate8 !0
  125. JL8 !loop
  126. # deal with toggle
  127. CMP_R15_Immediate8 !0
  128. JGE8 !print
  129. # process first byte of pair
  130. MOVE_R14_RAX
  131. LOAD32I_R15 %0
  132. JMP8 !loop
  133. # process second byte of pair
  134. :print
  135. # update the sum and store in output
  136. SHL_R14_Immediate8 !4
  137. ADD_RAX_R14
  138. STORE8_al_Absolute32 &output
  139. # flip the toggle
  140. LOAD32I_R15 %-1
  141. # Print our Hex
  142. LOAD32I_RDX %1 # set the size of chars we want
  143. LOAD32I_RSI &output # What we are writing
  144. LOAD32I_RDI %1 # Stdout File Descriptor
  145. LOAD32I_RAX %1 # the syscall number for write
  146. SYSCALL # call the Kernel
  147. JMP8 !loop
  148. :Done
  149. # program completed Successfully
  150. LOAD32I_RDI %0 # All is well
  151. LOAD32I_RAX %60 # put the exit syscall number in rax
  152. SYSCALL # Call it a good day
  153. # Where we are putting our output
  154. :output
  155. # Reserve 4bytes of Zeros
  156. NULL
  157. # Where we get our input
  158. :input
  159. # Reserve 4bytes of Zeros
  160. NULL
  161. :ELF_end