Guest User

Untitled

a guest
Oct 21st, 2019
91
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .bss
  2.  
  3. BF_MEM: .skip 10000
  4. OP_BRCS: .skip 10000
  5. CL_BRCS: .skip 10000
  6.  
  7. BRACE_PAIRS: .quad
  8.  
  9. .text
  10. printbf: .asciz "Running the program:\n%s\n\n"
  11. charfmt: .asciz "%c"
  12.  
  13. .global brainfuck
  14. # ***********************************************************************
  15. # * Subroutine: main
  16. # * Description: Application entry point
  17. # ***********************************************************************
  18. brainfuck:
  19. push %rbp # adding current address to stack
  20. movq %rsp, %rbp # storing the current position on stack
  21.  
  22. call print_info # calling the print_info subroutine
  23. call process_braces # find matches for the closing braces
  24. call run_bf
  25.  
  26. movq %rbp, %rsp # restoring stack
  27. pop %rbp # popping from stack
  28. ret
  29.  
  30.  
  31. # ***********************************************************************
  32. # * Subroutine: print_info
  33. # * Description: Just prints the current program to the console
  34. # ***********************************************************************
  35. print_info:
  36. push %rbp # adding current address to stack
  37. movq %rsp, %rbp # storing the current position on stack
  38. subq $8, %rsp
  39. movq %rax, -8(%rbp)
  40. movq %rax, %rsi
  41. movq $printbf, %rdi
  42. movq $0, %rax # clearing vector register
  43. call printf
  44. movq -8(%rbp), %rax # restoring the pointer to the program
  45. movq %rbp, %rsp # restoring stack
  46. pop %rbp # popping from stack
  47. ret
  48.  
  49.  
  50. # ***********************************************************************
  51. # fills BRACKETS in with matching closing braces for every opening
  52. # brace (count opening braces in run_bf)
  53. # ***********************************************************************
  54. process_braces:
  55. push %rbp # adding current address to stack
  56. movq %rsp, %rbp # storing the current position on stack
  57.  
  58. movq $0, %rcx # FOR DEBUGGING PURPOSES ONLY, SO I HAVE THE ADDRESS OF BRACKETS
  59. lea CL_BRCS(%rcx), %rcx # FOR DEBUGGING PURPOSES ONLY, SO I HAVE THE ADDRESS OF BRACKETS
  60.  
  61. movq $0, %rcx # FOR DEBUGGING PURPOSES ONLY, SO I HAVE THE ADDRESS OF BRACKETS
  62. lea OP_BRCS(%rcx), %rcx # FOR DEBUGGING PURPOSES ONLY, SO I HAVE THE ADDRESS OF BRACKETS
  63.  
  64. movq $0, %rbx # pgm symbol pointer
  65. movq $0, %rcx # clearing rcx for easier debugging
  66. movq $-1, %r8 # opening brace counter (starts at -1 so it hits 0 for the first brace pair)
  67.  
  68. jmp check_brace
  69.  
  70. # ***********************************************************************
  71. # for loop that checks for opening braces
  72. # ***********************************************************************
  73. next_char:
  74. incq %rbx
  75.  
  76. check_brace:
  77. movb (%rax,%rbx), %cl
  78.  
  79. cmpb $'[', %cl
  80. je match_brace
  81. cmpb $0, %cl
  82. je end_brace_check
  83.  
  84. jmp next_char
  85.  
  86.  
  87. # ***********************************************************************
  88. # match checker, cycles through the symbols after the opening brace
  89. # until it finds the matching closing brace
  90. # ***********************************************************************
  91. match_brace:
  92. incq %r8 # found a brace so increase brace counter
  93. movq %rbx, %r9 # current symbol
  94. movq $1, %rdx # level counter
  95. open_brace_nxt:
  96. incq %r9
  97. movb (%rax,%r9), %cl
  98.  
  99. cmpb $']', %cl
  100. je level_down
  101. cmpb $'[', %cl
  102. je level_up
  103. cmpb $0, %cl # should never trigger, but could in case of a malformed file
  104. je end_brace_check
  105.  
  106. jmp open_brace_nxt
  107. level_down:
  108. decq %rdx # decreasing level
  109.  
  110. cmpq $0, %rdx # check if we hit 0, that means we found our matching brace
  111. je found_match
  112.  
  113. jmp open_brace_nxt
  114. level_up:
  115. incq %rdx # can't encounter 0 by increasing, so no check needed
  116. jmp open_brace_nxt
  117.  
  118. # ***********************************************************************
  119. # When a matching close brace is found, it's inserted into the CL_BRCS
  120. # on the position of the corresponding opening brace (the the first opening
  121. # brace will have it's closing brace stored at CL_BRCS($0))
  122. # ***********************************************************************
  123. found_match:
  124. movq %rbx, OP_BRCS(,%r8,8) # saving the opening brace
  125. movq %r9, CL_BRCS(,%r8,8) # saving the closing brace
  126. jmp next_char
  127. end_brace_check:
  128. incq %r8
  129. movq %r8, BRACE_PAIRS
  130. movq %rbp, %rsp # restoring stack
  131. pop %rbp # popping from stack
  132. ret
  133.  
  134. # ***********************************************************************
  135. # Runs the brainfuck program
  136. # ***********************************************************************
  137.  
  138. run_bf:
  139. push %rbp # adding current address to stack
  140. movq %rsp, %rbp # storing the current position on stack
  141. subq $16, %rsp
  142. movq %rax, -8(%rbp) # for restoring after put/getchar call
  143.  
  144. movq $0, %rcx # FOR DEBUGGING PURPOSES ONLY, SO I HAVE THE ADDRESS OF BF_MEM
  145. lea BF_MEM(%rcx), %rcx # FOR DEBUGGING PURPOSES ONLY, SO I HAVE THE ADDRESS OF BF_MEM
  146.  
  147. movq $0, %rbx # pgm symbol pointer
  148. movq $0, %rcx # current symbol
  149. movq $0, %rdx # pgm memory pointer
  150. movq $0, %r8 # loop level
  151. jmp load_char # first time increasing rbx is skipped
  152. next_sym:
  153. incq %rbx
  154. load_char:
  155. movb (%rax,%rbx,1), %cl
  156.  
  157. cmpb $'+', %cl
  158. je inc_val
  159. cmpb $'-', %cl
  160. je dec_val
  161. cmpb $'>', %cl
  162. je inc_ptr
  163. cmpb $'<', %cl
  164. je dec_ptr
  165. cmpb $'[', %cl
  166. je open_loop
  167. cmpb $']', %cl
  168. je close_loop
  169. cmpb $'.', %cl
  170. je put_char
  171. cmpb $',', %cl
  172. je get_char
  173. cmpb $0, %cl
  174. je end_pgm
  175.  
  176. inc_val:
  177. incb BF_MEM(%rdx)
  178. jmp next_sym
  179.  
  180. dec_val:
  181. decb BF_MEM(%rdx)
  182. jmp next_sym
  183.  
  184. inc_ptr:
  185. incq %rdx
  186. jmp next_sym
  187.  
  188. dec_ptr:
  189. decq %rdx
  190. jmp next_sym
  191.  
  192.  
  193. # ***********************************************************************
  194.  
  195.  
  196. open_loop:
  197. cmpb $0, BF_MEM(%rdx)
  198. je end_loop
  199. jmp next_sym
  200. end_loop:
  201. movq $0, %r8
  202. check_close_brace:
  203. cmpq BRACE_PAIRS, %r8
  204. jge brace_not_found
  205.  
  206. cmpq OP_BRCS(,%r8, 8), %rbx
  207. je close_brace_found
  208.  
  209. incq %r8
  210. jmp check_close_brace
  211. close_brace_found:
  212. movq CL_BRCS(,%r8, 8), %rbx
  213. jmp next_sym
  214.  
  215.  
  216. # ***********************************************************************
  217.  
  218.  
  219. close_loop:
  220. movq $0, %r8
  221. check_open_brace:
  222. cmpq BRACE_PAIRS, %r8
  223. jge brace_not_found
  224.  
  225. cmpq CL_BRCS(,%r8, 8), %rbx
  226. je open_brace_found
  227.  
  228. incq %r8
  229. jmp check_open_brace
  230. open_brace_found:
  231. movq OP_BRCS(,%r8, 8), %rbx
  232. jmp load_char # since we need to actually read the [ again
  233.  
  234.  
  235. # ***********************************************************************
  236.  
  237.  
  238. put_char:
  239. movq $0, %rax
  240. movq %rdx, -16(%rbp)
  241.  
  242. movq $charfmt, %rdi
  243. movzbq BF_MEM(%rdx), %rsi
  244. movq $1, %rdx
  245.  
  246. call printf
  247.  
  248. movq -16(%rbp), %rdx
  249. movq -8(%rbp), %rax
  250. jmp next_sym
  251.  
  252. get_char:
  253. movq $0, %rax
  254. leaq BF_MEM(%rdx), %rdi
  255. call getchar
  256. movq -8(%rbp), %rax
  257. jmp next_sym
  258.  
  259. brace_not_found:
  260. movq $10, %rax # error code, should not happen in case of a proper program
  261. end_pgm:
  262. movq %rbp, %rsp # restoring stack
  263. pop %rbp # popping from stack
  264. ret
RAW Paste Data