asmg0.asm 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. ;; This file is part of asmc, a bootstrapping OS with minimal seed
  2. ;; Copyright (C) 2018 Giovanni Mascellani <gio@debian.org>
  3. ;; https://gitlab.com/giomasce/asmc
  4. ;; This program 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. ;; This program is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;; GNU General Public License for more details.
  12. ;; You should have received a copy of the GNU General Public License
  13. ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. PROGRAM_SIZE equ 0x100000
  15. SKIP_SIZE equ 0x1000000
  16. entry:
  17. ;; Store the address of the script in ESI
  18. mov esi, initrd
  19. ;; Skip some space in order not to touch other data; align to
  20. ;; 4 and set the stack pointer
  21. mov edi, esi
  22. add edi, SKIP_SIZE
  23. and edi, 0xffffff0
  24. mov esp, edi
  25. ;; Fill the program with 0x90 (NOPs)
  26. mov edx, edi
  27. mov ecx, PROGRAM_SIZE
  28. nops_fill:
  29. cmp ecx, 0
  30. je nops_filled
  31. sub ecx, 1
  32. mov BYTE [edx], 0x90
  33. add edx, 1
  34. jmp nops_fill
  35. nops_filled:
  36. ;; Initialize the accumulator (EAX) to 0
  37. mov eax, 0
  38. ;; Use ECX to backup the original EDI value
  39. mov ecx, edi
  40. compile_char:
  41. mov ebx, 0
  42. mov bl, [esi]
  43. cmp bl, 0x09
  44. je compile_loop
  45. cmp bl, 0x0a
  46. je compile_loop
  47. cmp bl, 0x0d
  48. je compile_loop
  49. cmp bl, 0x20
  50. je compile_loop
  51. cmp bl, 0x23
  52. je skip_comment
  53. cmp bl, 0x43
  54. je code_C
  55. cmp bl, 0x47
  56. je code_G
  57. cmp bl, 0x4d
  58. je code_M
  59. cmp bl, 0x50
  60. je code_P
  61. cmp bl, 0x52
  62. je code_R
  63. cmp bl, 0x53
  64. je code_S
  65. cmp bl, 0x70
  66. je code_p
  67. cmp bl, 0x69
  68. je code_i
  69. cmp bl, 0x6f
  70. je code_o
  71. cmp bl, 0x73
  72. je code_s
  73. cmp bl, 0x7a
  74. je code_z
  75. sub bl, 0x30
  76. cmp bl, 0x10
  77. jb code_digit
  78. sub bl, 0x31
  79. cmp bl, 0x6
  80. jb code_hex_digit
  81. ;; Invalid code, failing...
  82. failure:
  83. mov eax, 0xffffffff
  84. jmp shutdown
  85. compile_loop:
  86. add esi, 1
  87. jmp compile_char
  88. skip_comment:
  89. cmp BYTE [esi], 0xa
  90. je compile_loop
  91. add esi, 1
  92. jmp skip_comment
  93. ;; Process a digit into the accumulator
  94. code_hex_digit:
  95. add bl, 10
  96. code_digit:
  97. mov edx, 16
  98. mul edx
  99. add eax, ebx
  100. jmp compile_loop
  101. ;; Zero accumulator
  102. code_z:
  103. mov eax, 0
  104. jmp compile_loop
  105. ;; Jump to position in the accumulator, failing if going backward
  106. code_S:
  107. add eax, ecx
  108. cmp eax, edi
  109. jb failure
  110. mov edi, eax
  111. jmp compile_loop
  112. ;; Stop interpreting and call the code
  113. code_s:
  114. ;; Check that we did not overflow the allocated 1MB
  115. mov edx, ecx
  116. add edx, PROGRAM_SIZE
  117. cmp edi, edx
  118. ja failure
  119. ;; Push the source end
  120. add esi, 1
  121. push esi
  122. ;; Call the compiled code
  123. call ecx
  124. ;; call dump_code_and_die
  125. jmp shutdown
  126. ;; Emit push
  127. code_P:
  128. mov bl, 0x68
  129. call emit
  130. mov ebx, eax
  131. call emit32
  132. jmp compile_loop
  133. ;; Emit pop
  134. code_p:
  135. mov bl, 0x58
  136. call emit
  137. jmp compile_loop
  138. ;; Emit in
  139. code_i:
  140. ;; xor eax, eax; pop edx; in al, dx; push eax
  141. mov bl, 0x31
  142. call emit
  143. mov bl, 0xc0
  144. call emit
  145. mov bl, 0x5a
  146. call emit
  147. mov bl, 0xec
  148. call emit
  149. mov bl, 0x50
  150. call emit
  151. jmp compile_loop
  152. ;; Emit out
  153. code_o:
  154. ;; pop eax; pop edx; out dx, al
  155. mov bl, 0x58
  156. call emit
  157. mov bl, 0x5a
  158. call emit
  159. mov bl, 0xee
  160. call emit
  161. jmp compile_loop
  162. ;; Emit CALL
  163. code_C:
  164. ;; call target
  165. mov bl, 0xe8
  166. call emit
  167. mov ebx, eax
  168. add ebx, ecx
  169. sub ebx, edi
  170. sub ebx, 4
  171. call emit32
  172. jmp compile_loop
  173. ;; Emit function prologue
  174. code_G:
  175. ;; push ebp; mov ebp, esp
  176. mov bl, 0x55
  177. call emit
  178. mov bl, 0x89
  179. call emit
  180. mov bl, 0xe5
  181. call emit
  182. jmp compile_loop
  183. ;; Emit function epilogue
  184. code_R:
  185. ;; pop ebp; ret
  186. mov bl, 0x5d
  187. call emit
  188. mov bl, 0xc3
  189. call emit
  190. jmp compile_loop
  191. ;; Retrieve function parameter
  192. code_M:
  193. ;; pop eax; push DWORD [ebp+eax*4+8]
  194. mov bl, 0x58
  195. call emit
  196. mov bl, 0xff
  197. call emit
  198. mov bl, 0x74
  199. call emit
  200. mov bl, 0x85
  201. call emit
  202. mov bl, 0x08
  203. call emit
  204. jmp compile_loop
  205. emit:
  206. mov [edi], bl
  207. add edi, 1
  208. ret
  209. emit32:
  210. mov [edi], ebx
  211. add edi, 4
  212. ret