Punica_Granatum

ass2

Nov 8th, 2018
213
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # PURPOSE:   This program converts an input text file to an output text file with the base64 encoding.
  2. #
  3. # PROCESSING: 1) Open the input file
  4. #             2) Open the output file
  5. #             4) While we're not at the end of the input file
  6. #               a) read part of the file into our piece of memory
  7. #               b) go through each byte of memory
  8. #                  convert to base64
  9. #               c) write the piece of memory to the output file
  10.  
  11. .section .data  #Data storage
  12.  
  13.    base64:         #Lookup table
  14.        .ascii "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\0"
  15.  
  16.  
  17. #######CONSTANTS########
  18.  
  19.    # System call numbers
  20.    .equ SYS_OPEN, 2
  21.    .equ SYS_READ, 0
  22.    .equ SYS_WRITE, 1
  23.    .equ SYS_CLOSE, 3
  24.    .equ SYS_EXIT, 60
  25.  
  26.    # Options for open   (look at /usr/include/asm/fcntl.h for
  27.    #                    various values.  You can combine them
  28.    #                    by adding them)
  29.    .equ O_RDONLY, 0                  # Open file options - read-only
  30.    .equ O_CREAT_WRONLY_TRUNC, 03101  # Open file options - these options are:
  31.                                      # CREAT - create file if it doesn't exist
  32.                                       # WRONLY - we will only write to this file
  33.                                       # TRUNC - destroy current file contents, if any exist
  34.  
  35.     .equ O_PERMS, 0666                # Read & Write permissions for everyone
  36.  
  37.     # End-of-file result status
  38.     .equ END_OF_FILE, 0  # This is the return value of read() which
  39.                          # means we've hit the end of the file
  40.  
  41. #######BUFFERS#########
  42.  
  43. .section .bss
  44.    # This is where the data is loaded into from
  45.    # the data file and written from into the output file.
  46.    # It should never exceed 16,000 for various reasons.
  47.    .equ BUFFER_SIZE_INPUT, 600
  48.    .lcomm BUFFER_DATA_INPUT, BUFFER_SIZE_INPUT
  49.  
  50.    .equ BUFFER_SIZE_OUTPUT, 900
  51.    .lcomm BUFFER_DATA_OUTPUT, BUFFER_SIZE_OUTPUT
  52.  
  53.  
  54. #######PROGRAM CODE###
  55.  
  56.    .section .text
  57.  
  58.    # STACK POSITIONS
  59.    .equ ST_SIZE_RESERVE, 16        # Space for local variables
  60.                                    # Note: Offsets are RBP-based, which is set immediately at program start
  61.    .equ ST_FD_IN, -16              # Local variable for input file descriptor
  62.    .equ ST_FD_OUT, -8              # Local variable for output file descriptor
  63.    .equ ST_ARGC, 0                 # Number of arguments
  64.    .equ ST_ARGV_0, 8               # Name of program
  65.    .equ ST_ARGV_1, 16              # Input file name
  66.    .equ ST_ARGV_2, 24              # Output file name
  67.  
  68.    .globl _start
  69. _start:
  70.    ###INITIALIZE PROGRAM###
  71.    movq %rsp, %rbp
  72.    subq $ST_SIZE_RESERVE, %rsp      # Allocate space for our file descriptors on the stack
  73.    ###CHECK PARAMETER COUNT###
  74.    cmpq $3, ST_ARGC(%rbp)
  75.    je open_files
  76.    movq $-1, %rdi                   # Our return value for parameter problems
  77.    movq $SYS_EXIT, %rax
  78.    syscall
  79.  
  80. open_files:
  81. open_fd_in:
  82.    ###OPEN INPUT FILE###
  83.    movq ST_ARGV_1(%rbp), %rdi  # Input filename into %rdi
  84.    movq $O_RDONLY, %rsi        # Read-only flag
  85.    movq $O_PERMS, %rdx         # This doesn't really matter for reading
  86.     movq $SYS_OPEN, %rax        # Specify "open"
  87.     syscall                     # Call Linux
  88.     cmpq $0, %rax               # Check success
  89.     jl exit                     # In case of error simply terminate
  90.  
  91. store_fd_in:
  92.     movq  %rax, ST_FD_IN(%rbp)  # Save the returned file descriptor
  93.  
  94. open_fd_out:
  95.     ###OPEN OUTPUT FILE###
  96.     movq ST_ARGV_2(%rbp), %rdi        # Output filename into %rdi
  97.     movq $O_CREAT_WRONLY_TRUNC, %rsi  # Flags for writing to the file
  98.     movq $O_PERMS, %rdx               # Permission set for new file (if it's created)
  99.    movq $SYS_OPEN, %rax              # Open the file
  100.    syscall                           # Call Linux
  101.    cmpq $0, %rax                     # Check success
  102.    jl close_input                    # In case of error close input file (already open!)
  103.  
  104. store_fd_out:
  105.    movq %rax, ST_FD_OUT(%rbp)        # Store the file descriptor
  106.  
  107.    ###BEGIN MAIN LOOP###
  108. read_loop_begin:
  109.  
  110.    ###READ IN A BLOCK FROM THE INPUT FILE###
  111.    movq ST_FD_IN(%rbp), %rdi           # Get the input file descriptor
  112.    movq $BUFFER_DATA_INPUT, %rsi       # The location to read into
  113.    movq $BUFFER_SIZE_INPUT, %rdx       # The size of the buffer
  114.    movq $SYS_READ, %rax
  115.    syscall                             # Size of buffer read is returned in %eax
  116.  
  117.    ###EXIT IF WE'VE REACHED THE END###
  118.     cmpq $END_OF_FILE, %rax       # Check for end of file marker
  119.     jle end_loop                  # If found (or error), go to the end
  120.     movq $0, %rcx                 # Registry for counting data
  121.  
  122.  
  123. continue_read_loop:
  124.     ###CONVERT TO BASE64###
  125.     addq $3, %rcx                 #adds 3 to rcx to check data bounds
  126.     cmpq %rcx, %rax               #compares counter to actual data to check bounds
  127.     jle end_loop                  #jumps to end if counter exceeds data
  128.     subq $3, %rcx                 #subtracts rcx to keep counter accurate
  129.  
  130.     movq $BUFFER_DATA_INPUT, %rdx # moves input data address to rdx
  131.     #move byte 1
  132.     movb 0(%rdx,%rcx,1), %dil     # moves actual data to dil
  133.     incq %rcx                     # increment pointer
  134.     shlq $8, %rdi                 # moves rdi by one pos so data doesn't get overwritten
  135.    #move byte 2
  136.    movb 0(%rdx,%rcx,1), %dil     # moves actual data to dil
  137.    incq %rcx                     # increment pointer
  138.    shlq $8, %rdi                 # moves rdi by one pos so data doesn't get overwritten
  139.     #move byte 3
  140.     movb 0(%rdx,%rcx,1), %dil     # moves actual data to dil
  141.     incq %rcx                     # increment pointer
  142.  
  143.  
  144.     call convert_to_base64        # Note: RAX may (will) be destroyed (caller-safe!),
  145.                                   # but will be returned identically as return value
  146.  
  147.     ###WRITE THE BLOCK OUT TO THE OUTPUT FILE###
  148.     movq ST_FD_OUT(%rbp), %rdi    # File to use
  149.     movq $BUFFER_DATA_OUTPUT, %rsi       # Location of  buffer
  150.     movq %rax, %rdx               # Size of buffer (=number of bytes actually read/converted)
  151.     movq $SYS_WRITE, %rax
  152.     syscall
  153.  
  154.     ###CHECK WRITE SUCCESS###
  155.     popq %rbx                     # Retrieve number of bytes read
  156.     addq $8, %rsp                 # Remove stack alignment space
  157.     cmpq %rax, %rbx               # Compare number read to written
  158.     jne end_loop                  # If not the same, terminate program
  159.     ###CONTINUE THE LOOP###
  160.     jmp read_loop_begin
  161.  
  162. end_loop:
  163.  
  164.     ###CLOSE THE FILES###
  165.     # NOTE - we don't need to do error checking on these, because
  166.    #        error conditions don't signify anything special here
  167.     #        and there is nothing for us to do anyway
  168.     movq ST_FD_OUT(%rbp), %rdi
  169.     movq $SYS_CLOSE, %rax
  170.     syscall
  171.  
  172. close_input:
  173.     movq ST_FD_IN(%rbp), %rdi
  174.     movq $SYS_CLOSE, %rax
  175.     syscall
  176.  
  177. exit:
  178.     ###EXIT###
  179.     movq $0, %rdi          # Standard return value for all cases
  180.     movq $SYS_EXIT, %rax
  181.     syscall
  182.  
  183.  
  184. #Actual function which does the converting. Takes in 3 bytes of input and changes them to 4 bytes according to the base64 lookup table.
  185. convert_to_base64:
  186.  
  187.     movq %rdx, %r8                                      #copy 6 bits into rsi
  188.     salq $6, %rdx                                       #delete 6 bits being processed from source
  189.     andq $0b0000000000000000000000000111111, %r8        #keep only last six bits
  190.  
  191.  
  192.  
  193. convert_loop:
  194.  
  195.  
  196.  
  197. next_byte:
  198.  
  199.  
  200. end_convert_loop:
  201.     movq %rdi, %rax        # Store number of chars converted into RAX as return value
  202.     popq %rbx
  203.     movq %rbp, %rsp
  204.     popq %rbp
  205.     ret
RAW Paste Data