HOMEWORK – 2
Problem – 1
RISC-V code for sum of natural numbers.
.data
number: .word 5 # Example value to process
.text
.globl main
main:
la a0, number # Load the address of the variable "number"
lw a0, 0(a0) # Load the actual value from memory into a0
call sum # Invoke the sum function
mv a1, a0 # Move the result from a0 to a1
li a7, 10 # Prepare for exit system call
ecall # Terminate the program
sum:
addi sp, sp, -8 # Create space on the stack
sw ra, 4(sp) # Save the return address onto the stack
sw a0, 0(sp) # Store the input argument n onto the stack
beqz a0, base_case # If n is zero, jump to base case
addi a0, a0, -1 # Decrease n by 1
call sum # Execute the sum function recursively
lw t0, 0(sp) # Retrieve the original value of n from the stack
add a0, a0, t0 # Compute the result: n + sum(n-1)
lw ra, 4(sp) # Restore the return address
addi sp, sp, 8 # Remove stack space
jr ra # Return to the calling function
base_case:
li a0, 0 # Set the return value to 0 when n is zero
lw ra, 4(sp) # Restore the return address
addi sp, sp, 8 # Remove stack space
jr ra # Return to the calling function
Problem -2
RISC-V Code for multiplication using repeated addition
.text
.globl multiply
multiply:
beq x1, zero, end # if x is 0, return 0
beq x2, zero, end # if y is 0, return 0
li t1, 0 # initialize result to 0
loop:
add t1, t1, x2 # add y
addi x1, x1, -1 # decrement x
bne x1, zero, loop # repeat until x is 0
end:
mv a0, t1 # move result to a0 to return
ret
Problem – 3
RISC-V function to convert the string to upper case
.data
x: .word 3 # Sample input value x
y: .word 4 # Sample input value y
string: .asciz "hello" # Sample input string
.text
.globl main
main:
la a0, string # Load the address of the string into a0
call to_upper # Call the function to convert the string to uppercase
li a7, 10 # Prepare for the exit system call
ecall # Exit the program
to_upper:
lb t0, 0(a0) # Load a byte (character) from the string
beqz t0, done # If the character is null (end of string), proceed to done
li t1, 97 # Load ASCII value for 'a'
li t2, 122 # Load ASCII value for 'z'
blt t0, t1, skip # If the character is less than 'a', skip conversion
bgt t0, t2, skip # If the character is greater than 'z', skip conversion
addi t0, t0, -32 # Convert lowercase to uppercase by adjusting ASCII value
sb t0, 0(a0) # Store the updated character back into the string
skip:
addi a0, a0, 1 # Move to the next character in the string
j to_upper # Repeat the process for the next character
done:
jr ra # Return to the caller function
Problem – 4
RISC-V Program to Check if a Number is Even
.text
.globl is_even
is_even:
andi t0, a0, 1 # check if the least significant bit is 1
beq t0, zero, even # if zero, number is even
li a0, 0 # return 0 for odd
ret
even:
li a0, 1 # return 1 for even
ret
Problem – 5
Convert the RISC-V code to C
#include <stdio.h>
int main() {
int x28 = 0; // Initialize x28 to 0
int x29; // Declaration of x29 (initial value not set)
int *x10; // Declaration of a pointer x10 to an integer array (base address)
int x11 = 0; // Initialize x11 to 0 for sum accumulation
while (x28 < x29) { // Start loop: continue as long as x28 is less than x29
int x12 = x28 * 4; // Compute the offset by multiplying x28 by 4 (size of an int)
x12 = x12 + x10; // Increment the offset by the base address stored in x10
int x7 = *(x12); // Load the integer value from the memory location pointed to by x12
x11 = x11 + x7; // Add the loaded value to x11
x28++; // Increment x28 for the next iteration
}
return 0; // End of the program
}
Problem – 6
Snippet of code to be replaced :->
mul x12, x28, 4 # Perform multiplication of x28 by 4
add x12, x12, x10 # Calculate the effective address by adding x10 (base address) to the result
Problem – 7
Binary Representation of RISC-V Instructions
To convert the given RISC-V assembly instructions into binary representation, we would need to consider the opcode, source and destination registers, and immediately
encoded values.
a. srl x12, x11, x10
• Opcode: 0000000 (for shift instructions)
• Function Code (funct3): 101 (for SRL)
• Destination Register (rd): 11000 (x12)
• Source Register 1 (rs1): 01011 (x11)
• Source Register 2 (rs2): 01010 (x10)
Binary : 0000000 01010 01011 101 01100 0110011
b. lw x10, 32(x2)
• Opcode: 0000011 (for load word)
• Function Code (funct3): 010 (for LW)
• Destination Register (rd): 01010 (x10)
• Base Register (rs1): 00010 (x2)
• Immediate: 0000000000100000 (32)
Binary: 0000000000100000 00010 010 01010 0000011
c. sb x11, 84(x10)
• Opcode: 0000011 (for store byte)
• Function Code (funct3): 000 (for SB)
• Source Register (rs1): 01010 (x10)
• Immediate: 0000000001010100 (84)
• Destination Register (rs2): 01011 (x11)
Binary: 0000001 01011 01010 010 010100 0100011
d. bne x5, x6, 0xc
• Opcode: 1100011 (for branch instructions)
• Function Code (funct3): 001 (for BNE)
• Source Register 1 (rs1): 00101 (x5)
• Source Register 2 (rs2): 00110 (x6)
• Immediate: 000000000000 (0xc)
Binary : 0 000010 00110 00101 001 1000 0 1100011