Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .section .data
- # System call numbers
- .equ OPEN, 2
- .equ WRITE, 1
- .equ READ, 0
- .equ CLOSE, 3
- .equ EXIT, 60
- # File modes
- .equ O_RDONLY, 0
- .equ O_CREAT_WRONLY_TRUNC, 03101
- .equ O_PERMS, 0666
- .equ END_OF_FILE, 0 # End of file
- # variables
- IMAGE_SIZE: .long 0 # bitmap data size
- IMAGE_WIDTH: .long 0 # bitmap width
- IMAGE_HEIGHT: .long 0 # bitmap height
- B_CHAR: .byte 66 # int value of letter B
- M_CHAR: .byte 77 # int value of letter M
- BITS_PER_PIXEL .word 24 # value of bits per pixel for our image
- COLOR_PALETTE .long 0 # color palette value for this assignment
- message_bytes: .quad 0 # the amount of bytes for the message
- .section .bss
- .equ BUFFER_SIZE, 256
- .lcomm WRITE_DATA, BUFFER_SIZE
- .equ HEADER_SIZE, 54
- .lcomm HEADER_DATA, HEADER_SIZE
- .section .text
- # RETURN VALUES
- .equ RETURN_SUCCESS, 0
- .equ RETURN_INVALID_NUM_ARGS, 1
- .equ RETURN_ERR_INPUT, 2
- .equ RETURN_ERR_OUTPUT, 3
- .equ RETURN_INVALID_FORMAT, 4
- .equ RETURN_MSG_TOO_LONG, 5
- # BMP HEADER OFFSETS
- .equ HO_B, 0
- .equ HO_M, 1
- .equ HO_SIZE_V3, 14
- .equ HO_WIDTH_PIXELS, 18
- .equ HO_HEIGHT_PIXELS, 22
- .equ HO_NUM_BITS_PIXEL, 28
- .equ HO_COMPRESSION, 30
- .equ HO_NUM_COLORS_PALETTE, 46
- .globl _start
- _start:
- ###INITIALIZE PROGRAM###
- # r12 = file descriptor (INPUT)
- # r13 = file descriptor (OUTPUT)
- popq %rdi # load number of arguments into rdi
- popq %rcx
- popq %rcx # Argument 0 - rcx = hidden message
- popq %r8 # Argument 1 - r8 = filepath(input)
- popq %r9 # Argument 2 - r9 = filepath(output)
- ### check for valid amount of arguments ###
- cmpq $4, %rdi
- jne error_arguments # jump to errorhandling
- ### check if the bmp-input file exists ###
- movq %r8, %rdi # move filepath(input) into %rdi
- movq $OPEN, %rax # move open file number into %rax
- movq $O_RDONLY, %rsi # move read only number into %rsi
- syscall # call linux to open the file :)
- cmpq $0, %rax # check if file opening was successfull (return == 0)
- jl error_open_file # jump to errorhandling
- movq %rax, %r12 # move file descriptor(input) from %rax to r12
- ### check the output file ###
- movq %r9, %rdi # move filepath(output) into %rdi
- movq $OPEN, %rax # move open file number into %rax
- movq $O_PERMS, %rdx # move permissions number into %rdx
- movq $O_CREAT_WRONLY_TRUNC, %rsi # move write only number into %rsi
- syscall # create the file
- cmpq $0, %rax # check if file creation was successful (return == 0)
- jl error_output_file
- movq %rax, %r13 # move file descriptor(output) from %rax to r13
- ### read the header information ####
- movq %r12, %rdi # move file descriptor(input) into %rdi
- movq $READ, %rax # move read file number into %rax
- movq $HEADER_DATA, %rsi # move starting address into %rsi
- movq $HEADER_SIZE, %rdx # move buffer length into %rdx
- syscall # do it (read the file)
- cmpq $0, %rax # check if file opening was successful
- jl error_read_file
- cmpq $HEADER_SIZE, %rax # check if header size is valid
- jl error_format
- ### check the header information ###
- movq $HEADER_DATA, %rbx
- movq $HO_B, %rdi # move offset for HO_B information into %rdi
- movb (%rbx, %rdi, 1), %ah # move the byte at offset into %ah
- movq $HO_M, %rdi # move offset for HO_M information into %rdi
- movb (%rbx, %rdi, 1), %al # move the bate at offset into %al
- cmpb B_CHAR, %ah # check if B is at the given position in the header
- jne error_format
- cmpb M_CHAR, %al # check if M is at the given position in the header
- jne error_format
- ### check the color depth information ###
- movq $HO_NUM_BITS_PIXEL, %rdi # move offset for $HO_NUM_BITS_PIXEL information into %rdi
- movb (%rbx, %rdi, 1), %al # move the byte at offset into %al
- inc %rbi # increment %rbi to get the the second part of the value
- movb (%rbx, %rdi, 1), %ah # move the byte at offset into %ah
- cmpw BITS_PER_PIXEL, %ax # check if color depth is valid in our file
- jne error_format
- ### check the compression method information ###
- movq $0, %rdi # the compression imformation has to be 0, so move 0 into %rdi
- movq $HO_COMPRESSION, %r14 # move the compression offset into %r14
- movl HEADER_DATA(%r10, %rdi, 4), %eax # move the compression information into %eax
- cmpl $0, %eax # check if the comperssion method is 0
- jne error_format
- ### check the color palette information ####
- movq $0, %rdi # move 0 into %rdi
- movq $HO_NUM_COLORS_PALETTE, %r14 # move the collor palette offset innto %r14
- movl HEADER_DATA(%r14, %rdi, 4), %eax # move the data into %eax
- cmpl $COLOR_PALETTE, %eax # the color palette information has to be 0
- jne error_format
- ### check the size of the image ###
- ## get width and height ##
- movq $0,%rdi # move 0 into %rdi
- movq $HO_WIDTH_PIXELS, %r14 # move offset for pixel width into %r14
- movl HEADER_DATA(%r14, %rdi, 4), IMAGE_WIDTH # move the value into variable width
- movq $HO_HEIGHT_PIXELS, %r14 # move offset for picel height into %r14
- movl HEADER_DATA(%r14, %rdi, 4), IMAGE_HEIGHT # move the value into the variable height
- ## actualy check the size ##
- movq $0, %rdi # move 0 into %rdi
- movq $HO_IMAGE_SIZE, %r14 # move offset for image size into %r14
- movl HEADER_DATA(%r14, %rdi, 4), IMAGE_SIZE # move the size information into the variable IMAGE_SIZE
- cmpl $0, IMAGE_HEIGHT # check if the height is negative
- jl negate_height
- jmp get_size
- negate_height:
- movl IMAGE_HEIGHT, %esi # move the image height into %esi
- neg %edi # negate the height value in %edi
- movl %edi, IMAGE_HEIGHT # move the postive height into the variable IMAGE_HEIGHT
- get_size:
- ### calculate the size of the image ###
- # esi = width
- # edi = height
- movl IMAGE_WIDTH, %esi # move image width into %esi
- movl IMAGE_HEIGHT, %edi # move image height into %edi
- imul %esi, %edi # multiply them to get the size of the image (pixels)
- imul $3, %edi # multiply the size by 3 to get the total bytes of the picture (1 pixel = 3 Byte (RGB))
- movq %r8, %rcx #
- call count_bytes #
- #
- add $1, %rax #
- imul $8, %rax #
- cmpl %esi, %eax #
- jle encoded_message
- jmp error_message_to_long
- encode_message:
- ### todo ... ###
- #####ERROR LOOPS#####
- # wrong amount of argumments #
- error_arguments:
- movq $RETURN_INVALID_NUM_ARGS, %rdi # load return error message
- jmp exit
- # something went wrong while opening input file #
- error_open_file:
- movq %rax, %r10 # preload file descriptor
- call close_file # call close file function
- movq $RETURN_ERR_INPUT, %rdi # load return error message
- jmp exit
- # somthing went wrong while creating output file #
- error_output_file:
- movq %rax, %r10 # preload file descriptor
- call close_file # call close file function
- movq $RETURN_ERR_OUTPUT, %rdi # load return error message
- jmp exit
- # somthing went wrong with reading the file #
- error_read_file:
- movq $RETURN_READ_ERROR, %rdi # load return message
- jmp exit
- # somthing went wrong with the format while reading file #
- error_format:
- movq %rax, %r10 # preload file descriptor
- call close_file # call close file function
- movq $RETURN_INVALID_FORMAT, %rdi # load return message
- jmp exit
- # message is too long for the image #
- error_message_to_long:
- movq %rax, %r10 # preload file descriptor
- call close_file # call close file function
- movq $RETURN_MSG_TOO_LONG,%rdi # load return error message
- jmp exit
- ###EXIT###
- exit:
- movq $0, %rbx
- movq $EXIT, %rax
- syscall
- ## close file function ##
- # closes the file from file descriptor in %r10 #
- .type close_file, @function
- close_file:
- ## save the registers ##
- pushq %rbp
- movq %rsp, %rbp
- pushq %rdi
- ## close the file ##
- movq $CLOSE, %rax # move close file number into %rax
- movq %r10, %rdi # move dile descriptor into rdi
- syscall # close file
- ## restore the registers ##
- popq %rdi
- movq %rbp, %rsp
- popq %rbp
- ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement