Advertisement
DavidCY

Untitled

Nov 20th, 2019
347
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .equ SYS_OPEN, 2
  2. .equ SYS_READ, 0
  3. .equ SYS_WRITE, 1
  4. .equ SYS_CLOSE, 3
  5. .equ SYS_EXIT, 60
  6.  
  7. .equ O_RDONLY, 0 # Open file options - read-only
  8. .equ O_CREAT_WRONLY_TRUNC, 03101
  9. .equ O_PERMS, 0666
  10. .equ END_OF_FILE, 0
  11.  
  12.  
  13. .section .bss
  14. .equ READ_BUFFER_SIZE, 500
  15. .lcomm READ_BUFFER_DATA, READ_BUFFER_SIZE
  16. .equ WRITE_BUFFER_SIZE, 1000
  17. .lcomm WRITE_BUFFER_DATA, WRITE_BUFFER_SIZE
  18.  
  19.  
  20. .section .text
  21.     .globl _start
  22.     .equ ST_SIZE_RESERVE, 16 # Space for local variables
  23.     .equ ST_FD_IN, -16 # Local variable for input file descriptor
  24.     .equ ST_FD_OUT, -8 # Local variable for output file descriptor
  25.     .equ ST_ARGC, 0 # Number of arguments (integer)
  26.     .equ ST_ARGV_0, 8 # Name of program (address = pointer to string)
  27.     .equ ST_ARGV_1, 16 # Input file name (address = pointer to string)
  28.     .equ ST_ARGV_2, 24 # Output file name (address = pointer to string)
  29.  
  30.  
  31. _start:
  32.     movq %rsp, %rbp
  33.     subq $ST_SIZE_RESERVE, %rsp
  34.     cmpq $3, ST_ARGC(%rbp)
  35.     je open_files
  36.     movq $-1, %rdi # Our return value for parameter problems
  37.     movq $SYS_EXIT, %rax
  38.     syscall
  39.  
  40.  
  41. open_files:
  42. open_fd_in:
  43.     movq ST_ARGV_1(%rbp), %rdi # Input filename into %rdi
  44.     movq $O_RDONLY, %rsi # Read-only flag
  45.     movq $O_PERMS, %rdx # This doesn't really matter for reading
  46.     movq $SYS_OPEN, %rax # Specify "open"
  47.     syscall # Call Linux
  48.     cmpq $0, %rax # Check success
  49.     jl exit # In case of error simply terminate
  50.     store_fd_in:
  51.         movq %rax, ST_FD_IN(%rbp) # Save the returned file descriptor
  52.  
  53. open_fd_out:
  54.     movq ST_ARGV_2(%rbp), %rdi # Output filename into %rdi
  55.     movq $O_CREAT_WRONLY_TRUNC, %rsi # Flags for writing to the file
  56.     movq $O_PERMS, %rdx # Permissions for new file (if created)
  57.     movq $SYS_OPEN, %rax # Open the file
  58.     syscall # Call Linux
  59.     cmpq $0, %rax # Check success
  60.     jl close_input # In case of error close input file
  61.  
  62. store_fd_out:
  63.     movq %rax, ST_FD_OUT(%rbp) # Store the file descriptor
  64.  
  65. read_loop_begin:
  66.     movq ST_FD_IN(%rbp), %rdi # Get the input file descriptor
  67.     movq $READ_BUFFER_DATA, %rsi # The location to read into
  68.     movq $READ_BUFFER_SIZE, %rdx # The size of the buffer
  69.     movq $SYS_READ, %rax
  70.     syscall # Size of buffer read is returned in %rax
  71.     cmpq $END_OF_FILE, %rax #Check for end of file marker (or error)
  72.     jle end_loop # If found, go to the end
  73.     continue_read_loop:
  74.         movq $READ_BUFFER_DATA, %rdi # Location of the buffer
  75.         movq %rax, %rsi # Size of the buffer
  76.         pushq $-1 # Dummy value for stack alignment
  77.         pushq %rax # Store bytes read for write check
  78.         call decode
  79.  
  80.  
  81. write_out_begin:    ###WRITE THE BLOCK OUT TO THE OUTPUT FILE###
  82.     movq ST_FD_OUT(%rbp), %rdi # File to use
  83.     movq $WRITE_BUFFER_DATA, %rsi # Location of buffer
  84.     movq %rax, %rdx # Buffer size (=number of bytes read)
  85.     movq $SYS_WRITE, %rax
  86.     syscall # Note: Check how much was written!
  87.     ###CHECK WRITE SUCCESS###
  88.     popq %rbx # Retrieve number of bytes read
  89.     addq $8, %rsp # Remove stack alignment space
  90.     cmpq %rax, %rbx # Compare number read to written
  91.     jne end_loop # If not the same, terminate program
  92.     jmp read_loop_begin #CONTINUE THE LOOP###
  93.  
  94. end_loop:
  95.     movq ST_FD_OUT(%rbp), %rdi
  96.     movq $SYS_CLOSE, %rax
  97.     syscall
  98.  
  99. close_input:
  100.     movq ST_FD_IN(%rbp), %rdi
  101.     movq $SYS_CLOSE, %rax
  102.     syscall
  103.  
  104. exit:
  105.     movq $0, %rdi
  106.     movq $SYS_EXIT, %rax
  107.     syscall
  108.  
  109. decode:
  110.     pushq %rbp # Prepare stack
  111.     movq %rsp, %rbp
  112.     pushq %rbx # Save RBX
  113.     movq %rdi, %rax
  114.     movq %rsi, %rbx
  115.     movq $0, %rdi
  116.  
  117.     # If a buffer with zero length was given us, just leave
  118.     cmpq $0, %rbx
  119.     je exit
  120.  
  121.    decode_loop:
  122.        call chars_to_byte
  123.        incq %rdi # Next byte
  124.        cmp $0xB8,%r10
  125.        jmp decode_loop
  126.  
  127.    call exit
  128.  
  129.  
  130. chars_to_byte:
  131.     movb (%rax,%rdi,1), %r8b #Get the current byte
  132.     call char_to_hex
  133.     mov %r8, %r10
  134.     sal $4, %r10
  135.  
  136.     incq %rdi # Next byte
  137.     movb (%rax,%rdi,1), %r8b #Get the following byte
  138.     call char_to_hex
  139.     add %r8, %r10
  140.     ret
  141.  
  142. char_to_hex:
  143.    cmp $'0', %r8
  144.    jl exit
  145.    cmp $'9', %r8
  146.    jg alpha_to_hex
  147.    jle number_to_hex
  148.    ret
  149.  
  150. alpha_to_hex:
  151.    cmp $'A', %r8
  152.    jl exit
  153.    cmp $'F', %r8
  154.    jg exit
  155.  
  156.     sub $'A', %r8
  157.     add $10, %r8
  158.    ret
  159.  
  160. number_to_hex:
  161.     sub $'0', %r8
  162.    ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement