# Lab 5 Name: G Jaswanth Roll No.: CS22B020 --- ## Question 1 ### **Code with loop** ```assembly= .data array: .word 1 2 3 4 5 6 7 8 9 10 11 12 str: .string " " .text la x1 array la x30 array li x2 12 li x3 12 loop: lw x4 44(x1) addi x4 x4 3 sw x4 44(x1) addi x1 x1 -4 addi x2 x2 -1 beq x2 x0 print j loop print: lw x4 0(x30) add a0 x4 x0 li a7 1 ecall la a0 str li a7 4 ecall addi x30 x30 4 addi x2 x2 1 beq x2 x3 exit j print exit: li a7 10 ecall ``` ### Output ![Screenshot 2024-02-28 212952](https://hackmd.io/_uploads/Hk_RzkTh6.png) ### **Code after unrolling by factor 4** ```assembly= .data array: .word 1 2 3 4 5 6 7 8 9 10 11 12 str: .string " " .text la x1 array la x3 array li x2 12 li x8 12 loop: lw x4 44(x1) lw x5 40(x1) lw x6 36(x1) lw x7 32(x1) addi x4 x4 3 addi x5 x5 3 addi x6 x6 3 addi x7 x7 3 sw x4 44(x1) sw x5 40(x1) sw x6 36(x1) sw x7 32(x1) addi x1 x1 -16 addi x8 x8 -4 beq x8 x0 print j loop print: lw x9 0(x3) add a0 x9 x0 li a7 1 ecall la a0 str li a7 4 ecall addi x3 x3 4 addi x2 x2 -1 bne x2 x0 print Exit: li a7 10 ecall ``` ### Output ![Screenshot 2024-02-28 220652](https://hackmd.io/_uploads/r12k7y6hT.png) ### Observations: We saw unrolled loop have higher IPC(instructions per cycle) than a normal loop, this may be due to * Unrolling reduces the overhead of branch instructions and loop control, leading to fewer pipeline stalls * It increases instruction-level parallelism by allowing multiple instructions from different iterations of the loop to be executed concurrently. * There's a reduced likelihood of branch mispredictions since there are fewer branches in the unrolled loop. Therefore, the unrolled loop execution typically yields a higher IPC compared to the normal loop execution. **console output** 4 5 6 7 8 9 10 11 12 13 14 --- ## Question 2 **Code** ```assembly= .data str: .string " " node1: .word 1 # value .word 0 # pointer to next node node2: .word 2 .word 0 node3: .word 3 .word 0 node4: .word 4 .word 0 node5: .word 5 .word 0 node6: .word 6 .word 0 node7: .word 7 .word 0 node8: .word 8 .word 0 node9: .word 9 .word 0 node10: .word 10 .word 0 .text # link the nodes la x1, node1 la x2, node2 la x3, node3 la x4, node4 la x5, node5 la x6, node6 la x7, node7 la x8, node8 la x9, node9 la x10, node10 sw x2, 4(x1) sw x3, 4(x2) sw x4, 4(x3) sw x5, 4(x4) sw x6, 4(x5) sw x7, 4(x6) sw x8, 4(x7) sw x9, 4(x8) sw x10, 4(x9) sw x0, 4(x10) # Set the last node's next pointer to NULL # reverse the linked list la x30, node1 # x30 points to the first node li x31, 0 # Initialize x31 (previous) to NULL li x20, 0 li x21, 10 #length of linked list reverse_loop: lw x20, 4(x30) # Load the next pointer of the current node sw x31, 4(x30) # Update the next pointer of the current node to the previous node mv x31, x30 # Update the previous node to the current node mv x30, x20 # Move to the next node bne x20 x0 reverse_loop # Repeat until t0 is not NULL mv x16 x31 print: #printing the values lw x18 0(x16) add a0 x18 x0 li a7 1 ecall la a0 str li a7 4 ecall addi x21 x21 -1 lw x19 4(x16) mv x16 x19 bne x21 x0 print # At this point, t1 points to the new head of the reversed list # You can use t1 or the label of the first node of the reversed list to access it ``` **2 a** Output: 10 9 8 7 6 5 4 3 2 1 ### Observations Each node in the linked list consists of two main parts: * Data: This is the actual information or payload stored in the node. It could be a single value or a collection of values. * Pointer: This is a memory address that points to the next node in the sequence. In RISC-V assembly language, pointers are typically represented using memory addresses stored in registers. Overall, a linked list in RISC-V assembly language provides a flexible data structure for storing and manipulating data in a non-contiguous manner, allowing for efficient insertion, deletion, and traversal of elements. --- ## Question 3 **Code** ```assembly= .data node1: .word 1,0 # the NULL pointer is 0 node2: .word 2,0 node3: .word 3,0 node4: .word 4,0 node5: .word 5,0 node6: .word 6,0 node7: .word 7,0 node8: .word 8,0 node9: .word 9,0 node10: .word 10,0 newNode: .word 11,0 buffer: .string " " .text j main create_node: la t0 node1 addi t0 t0 4 # curr = word storing address loop: lw t1 0(t0) addi t0 t0 8 # curr = next word storing address beq t1 x0 endloop bne t1 x0 loop endloop: addi t0 t0 -8 la t2 newNode sw t2 0(t0) jalr x0 ra 0 print_node: li a7, 4 # System call for print string la a0, buffer # Load the address of the buffer ecall # Print "Value: " lw a0, 0(a1) # Load the value of the current node li a7, 1 # System call number for printing integer ecall # Print the integer li a7, 4 # System call for print string la a0, 10 # Load the address of the newline character ecall # Print newline jr ra # Return main: # link the nodes la t0 node1 la t1 node2 sw t1 4(t0) la t0 node3 sw t0 4(t1) la t1 node4 sw t1 4(t0) la t0 node5 sw t0 4(t1) la t1 node6 sw t1 4(t0) la t0 node7 sw t0 4(t1) la t1 node8 sw t1 4(t0) la t0 node9 sw t0 4(t1) la t1 node10 sw t1 4(t0) jal ra create_node # Print the linked list la a1, node1 # a1 points to the first node loop_print: beqz a1, end_print # If a1 is NULL, end the loop lw a0, 0(a1) # Load the value of the current node jal ra, print_node # Print the value of the current node lw a1, 4(a1) # Move to the next node j loop_print end_print: # End of program li a7, 10 # System call number for exit ecall # Exit the program # Exit the program ``` **3 a** 1 2 3 4 5 6 7 8 9 10 11 **Observation:** * We linked numbers from * 1 2 3 4 5 6 7 8 9 10 * and inserted 11 at the end afterwards giving output as * 1 2 3 4 5 6 7 8 9 10 11 ---