Task 1.

  • Solution for task 1, part 2:
    .data
    
        # Data to encrypt
        data:   .ascii  "this is 16 bytes"
    
        # Encryption key
        key:    .ascii  "the key is here!"
    
        # Destination for encrypted data
        dest:   .space  16
    
    .text
    .globl  main
    
    main:
        la      a0, data       # Store address of the first byte of data in a0
        la      a2, key        # Store address of the first byte of key in a2
        la      a3, dest       # Store address of the first byte of dest in a3
        li	    a1, 16         # Store the length of the data in a1
        add     t0, a0, a1   # Store the address of the first byte after data in
                                # t0, which can be used as a stop condition for
                                # our loop
    
    loop:
        ble     t0, a0, end   # Check we haven't reached the end of the data
        lw      t1, (a0)
        lw      t2, (a2)
        xor     t3, t1, t2   # Xor the current word of data with the current word
                                # of key
        sw      t3, (a3)
        addi    a0, a0, 4     # Increment the data segment pointers
        addi    a2, a2, 4
        addi    a3, a3, 4
        b       loop            # Go back to the loop condition check
    
    end:
        li      a7, 10         # Make an exit system call
        ecall
      
    Note that the strings "this is 16 bytes" and "the key is here!" are 16 bytes long, hence aligned. (Why?) If you had used strings of a length not divisible by 4, you'd have to align them explicitly for example using the .align command that MIPS assembly provides.
  • Solution for task 1, part 2 (with a temporary register):
        add a2, a1, zero # Equivalent to 'move a2, a1'.
        add a1, a0, zero
        add a0, a2, zero
      
  • Solution for task 1, part 2 (without a temporary register):
        add a1, a1, a0   # Add them together, overwriting a1
        sub a0, a0, a1   # Subtract the sum of both from a0, leaving -(initial value of a1) in a0
        neg a0, a0        # Negate a0 to obtain the initial value of a1
        sub a1, a1, a0   # Subtract a0 from a1, leaving the initial value of a0 in a1
      
  • Solution for task 1, part 3:
    .text
    .globl main
    
    main:
        li  a0, 43110
        li  a7, 1              # 1 is the print integer ecall code
        ecall
        b exit
    
    exit:
        li  a7, 10             # 10 is the exit ecall code
        ecall
      
  • Solution for task 1, part 4 (only printing some of the 32 general purpose registers for brevity):
    .text
    .globl main
    
    main:
        jal     print       # 'Jump and link' - jump to the label, and put the address
                            # of the next command that would otherwise be executed in
                            # ra (return address) so we can jump back and resume
        mv    a0, a1
        jal     print
        mv    a0, a2
        jal     print
        mv    a0, a3
        jal     print
        mv    a0, t0
        jal     print
        mv    a0, t1
        jal     print
        mv    a0, t2
        jal     print
        mv    a0, t3
        jal     print
        mv    a0, t4
        jal     print
        mv    a0, t5
        jal     print
        mv    a0, t6
        jal     print
        b       exit
    
    print:
        li      a7, 1      # 1 is the print integer ecall code
        ecall
        jr      ra         # Jump back to the caller
    
    exit:
        li      a7, 10     # 10 is the exit ecall code
        ecall
      

    Task 2. For RARS you can use the following.

    		java -jar rars.jar  dec ae777 filename a0
    	      

    Here rars.jar is contains the RARS code, and the file containing the RISV-V assembly is in filename. Note that RARS has a Java API, so you can script RARS from Java, see the discussion here.

    Task 3. Here are the programs.