SHARE
TWEET

Untitled

a guest Oct 21st, 2019 85 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top