Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .equ SYS_OPEN, 2
- .equ SYS_READ, 0
- .equ SYS_WRITE, 1
- .equ SYS_CLOSE, 3
- .equ SYS_EXIT, 60
- .equ O_RDONLY, 0 # Open file options - read-only
- .equ O_CREAT_WRONLY_TRUNC, 03101
- .equ O_PERMS, 0666
- .equ END_OF_FILE, 0
- .section .bss
- .equ READ_BUFFER_SIZE, 500
- .lcomm READ_BUFFER_DATA, READ_BUFFER_SIZE
- .equ WRITE_BUFFER_SIZE, 1000
- .lcomm WRITE_BUFFER_DATA, WRITE_BUFFER_SIZE
- .section .text
- .globl _start
- .equ ST_SIZE_RESERVE, 16 # Space for local variables
- .equ ST_FD_IN, -16 # Local variable for input file descriptor
- .equ ST_FD_OUT, -8 # Local variable for output file descriptor
- .equ ST_ARGC, 0 # Number of arguments (integer)
- .equ ST_ARGV_0, 8 # Name of program (address = pointer to string)
- .equ ST_ARGV_1, 16 # Input file name (address = pointer to string)
- .equ ST_ARGV_2, 24 # Output file name (address = pointer to string)
- _start:
- movq %rsp, %rbp
- subq $ST_SIZE_RESERVE, %rsp
- cmpq $3, ST_ARGC(%rbp)
- je open_files
- movq $-1, %rdi # Our return value for parameter problems
- movq $SYS_EXIT, %rax
- syscall
- open_files:
- open_fd_in:
- movq ST_ARGV_1(%rbp), %rdi # Input filename into %rdi
- movq $O_RDONLY, %rsi # Read-only flag
- movq $O_PERMS, %rdx # This doesn't really matter for reading
- movq $SYS_OPEN, %rax # Specify "open"
- syscall # Call Linux
- cmpq $0, %rax # Check success
- jl exit # In case of error simply terminate
- store_fd_in:
- movq %rax, ST_FD_IN(%rbp) # Save the returned file descriptor
- open_fd_out:
- movq ST_ARGV_2(%rbp), %rdi # Output filename into %rdi
- movq $O_CREAT_WRONLY_TRUNC, %rsi # Flags for writing to the file
- movq $O_PERMS, %rdx # Permissions for new file (if created)
- movq $SYS_OPEN, %rax # Open the file
- syscall # Call Linux
- cmpq $0, %rax # Check success
- jl close_input # In case of error close input file
- store_fd_out:
- movq %rax, ST_FD_OUT(%rbp) # Store the file descriptor
- read_loop_begin:
- movq ST_FD_IN(%rbp), %rdi # Get the input file descriptor
- movq $READ_BUFFER_DATA, %rsi # The location to read into
- movq $READ_BUFFER_SIZE, %rdx # The size of the buffer
- movq $SYS_READ, %rax
- syscall # Size of buffer read is returned in %rax
- cmpq $END_OF_FILE, %rax #Check for end of file marker (or error)
- jle end_loop # If found, go to the end
- continue_read_loop:
- movq $READ_BUFFER_DATA, %rdi # Location of the buffer
- movq %rax, %rsi # Size of the buffer
- pushq $-1 # Dummy value for stack alignment
- pushq %rax # Store bytes read for write check
- call decode
- write_out_begin: ###WRITE THE BLOCK OUT TO THE OUTPUT FILE###
- movq ST_FD_OUT(%rbp), %rdi # File to use
- movq $WRITE_BUFFER_DATA, %rsi # Location of buffer
- movq %rax, %rdx # Buffer size (=number of bytes read)
- movq $SYS_WRITE, %rax
- syscall # Note: Check how much was written!
- ###CHECK WRITE SUCCESS###
- popq %rbx # Retrieve number of bytes read
- addq $8, %rsp # Remove stack alignment space
- cmpq %rax, %rbx # Compare number read to written
- jne end_loop # If not the same, terminate program
- jmp read_loop_begin #CONTINUE THE LOOP###
- end_loop:
- movq ST_FD_OUT(%rbp), %rdi
- movq $SYS_CLOSE, %rax
- syscall
- close_input:
- movq ST_FD_IN(%rbp), %rdi
- movq $SYS_CLOSE, %rax
- syscall
- exit:
- movq $0, %rdi
- movq $SYS_EXIT, %rax
- syscall
- decode:
- pushq %rbp # Prepare stack
- movq %rsp, %rbp
- pushq %rbx # Save RBX
- movq %rdi, %rax
- movq %rsi, %rbx
- movq $0, %rdi
- # If a buffer with zero length was given us, just leave
- cmpq $0, %rbx
- je exit
- decode_loop:
- call chars_to_byte
- incq %rdi # Next byte
- cmp $0xB8,%r10
- jmp decode_loop
- call exit
- chars_to_byte:
- movb (%rax,%rdi,1), %r8b #Get the current byte
- call char_to_hex
- mov %r8, %r10
- sal $4, %r10
- incq %rdi # Next byte
- movb (%rax,%rdi,1), %r8b #Get the following byte
- call char_to_hex
- add %r8, %r10
- ret
- char_to_hex:
- cmp $'0', %r8
- jl exit
- cmp $'9', %r8
- jg alpha_to_hex
- jle number_to_hex
- ret
- alpha_to_hex:
- cmp $'A', %r8
- jl exit
- cmp $'F', %r8
- jg exit
- sub $'A', %r8
- add $10, %r8
- ret
- number_to_hex:
- sub $'0', %r8
- ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement