---
# System prepended metadata

title: Lab x

---

# Lab 4
Name: Aditya Rghuveer
Roll No.:CS22B019

---
## Question 1
addi x10 , x0 , 3 # s = 3 
 addi x11 , x0 , 10 # i = 10
 addi x12 , x0 , 0 # 0
 add x9 , x8 , x0 # x8 is the base register
 Loop :
 beq x11 , x12 , Exit
 lw x13 , 0( x9 ) #load array[i] into x13
 add x13 , x10 , x13 # array[i]=s+array[i]
 addi x11 , x11 , -1 # i--
 addi x9 , x9 , 4 # x 9 = x 9 + 4
 j Loop
 Exit :


## Question 2
.data
    arr: .word 1,0,5,6,8,9,0,0,0
    size: .word 9
.text
    la x5 arr    # loading the address of array 
    add x6 x0 x0    # i = 0
    add x11 x0 x0    #variable1 to check if previous num is odd
    add x13 x0 x0     # variable2 to check if previous two consecutive nums are odd
    lw x4 size 
    loop:
        slli x7 x6 2     #shifting left logical immediately
        add x7 x7 x5
        lw x8 0(x7)    #x8 = arr[i]
        li x9 1     
        and x8 x8 x9    #if arr[i] is odd then x8 will be 1
        and x12 x8 x11    #x12 will be 1 if current and previous nums are odd
        and x14 x13 x8    #x14 will be 1 if current and previous two nums are odd 
        beq x14 x9 exit    
        add x13 x0 x12    #x13 = x12
        add x11 x0 x8    #x11 = x8
        addi x6 x6 1
        blt x6 x4 loop
   exit:
        add a0 x0 x14    #prints 1 if true and 0 if false
        li a7 1
        ecall
        
        
    
## Question 3
.data
  n: .word 0  # store the value of n

.align 3
  a: .word 0  # array to store input values
  b: .word 0  # array to store output values

.message:
  .asciz "enter value for n: "
  .newline
.text

main:
  # Print message to prompt user for input
  la a0, .message
  li a1, 1  # Print string from memory
  ecall

  # Read input for n
  li a7, 3  # read number
  ecall
  sw a0, n  # store n in memory

  # Calculate half of n
  lw a0, n   # load n
  addi a1, a0, -1  # subtract 1
  srai a2, a0, 1  # divide by 2 (shift right)

  # Loop through the input array
  li t0, 0  # loop counter
loop:
    # Check if reached end of array
    blt t0, n, endloop  # jump to end if counter >= n
# Read input for a[i]
  li a7, 3  # read syscall number
    ecall
    sw a0, 0(a), t0  # store input in a[i]

  # Check if even index and not the last element
   addi a3, t0, 1  # increment counter
    andi a3, a3, 1  # check if odd
    bne a3, zero, even  # jump to even case if odd

 # Check if first element
  beqz t0, first  # jump to first element case

even:
    # Calculate even index of b[i]
    sub a1, a2, t0  # subtract counter from half of n
    sll a1, a1, 1  # shift left by 1 to multiply by 2

# Access element in a[] and store in b[]
  lw a0, 0(a), t0  # load a[i]
   sw a0, 0(b), a1  # store in b[i]

   j loop  # continue loop

first:
    # Store first element in b[]
    lw a0, 0(a), t0  # load a[0]
    sw a0, 0(b)  # store in b[0]

   j loop  # continue loop

endloop:
  # Loop through the output array
  li t0, 0  # loop counter
loop_output:
    # Check if reached end of array
    blt t0, n, end_output  # jump to end if counter >= n

   # Load element from b[]
   lw a0, 0(b), t0  # load b[i]

   # Print output value
   li a1, 1  # Print integer
    ecall

# Print space
li a1, 4  # Print character from memory
   la a0, .newline
ecall

   # Increment counter
   addi t0, t0, 1
   j loop_output
end_output:
  # Exit program
  li a7, 93  # exit syscall number
  ecall

  # Should never reach here
  .word 0
      
      
## Question 4
.data
# String for prompting divisor input
divisor_prompt: .asciiz "enter value for divisor:\n"

.text
main:
# Read dividend
li a7, 5  # Load system call for reading integer
ecall
mv t0, a0  # Store dividend in t0

# Print prompt for divisor
la a0, divisor_prompt  # Load address of divisor prompt
li a7, 4  # Load system call for printing string
ecall

# Read divisor
li a7, 5  # Load system call for reading integer
ecall
mv t1, a0  # Store divisor in t1

# Initialize loop counter and k
li t2, 1  # Count initialized to 1
mv t3, t1  # Copy divisor to k

loop:
# Check loop condition
blt t0, t1, end_loop  # Branch to end if dividend < divisor

# Double divisor efficiently
sll t1, t1, 1  # Equivalent to k addition

# Check divisibility
blt t0, t1, next_iteration  # Branch if not divisible

# Increment count
addi t2, t2, 1

# Continue loop
j loop

next_iteration:
# Restore original divisor
sub t1, t1, t3

# Continue loop
j loop

end_loop:
# Print count
mv a0, t2  # Set argument to count value
li a7, 1  # Load system call for printing integer
ecall

# Exit program
li a7, 10  # Load system call for exit
ecall


## Question 5
# Define data section
.data
newline: .asciiz "\n"

elem1: .word 1, 0
elem2: .word 2, 0
elem3: .word 3, 0
elem4: .word 4, 0
new_elem: .word 99, 0

# Define text section
.text
main:

# Initialize head pointer (t0) to first element
la t0, elem1

# Initialize new element pointer (t4)
la t4, new_elem

# Link elements using loop
addi t1, t0, 4  # Start from second element pointer
loop:
# Check if end of linked list
beqz t1, done_linking
# Store next element address in current element's next pointer
sw t2, 0(t1)
# Move to next element
addi t1, t1, 4
# Load next element address into t2
lw t2, 0(t1)
j loop

done_linking:

# Print initial list (using recursive function)
li a0, t0  # Pass head pointer as argument
jal ra, print_list

# Insert new element at beginning
sw t4, 0(t0)  # Store new element address in head's next pointer
sw t0, 0(t4)  # Store old head address in new element's next pointer
addi t0, t4, 0  # Update head pointer to new element

# Print updated list
li a0, t0  # Pass updated head pointer as argument
jal ra, print_list

# Exit program
li a7, 10
ecall

# Function to print linked list recursively
print_list:
# Check if end of list
beqz a0, done_printing
# Load data from current node
lw t1, 0(a0)
# Print data
mv a0, t1
li a7, 1
ecall
# Print newline
la a0, newline
li a7, 4
ecall
# Move to next element
lw a0, 4(a0)
# Recursively call print_list
jal ra, print_list

done_printing:
ret


## Question 6
.align 3
FREE_LIST: .word 0

.text
malloc:
  # Prologue
  addi sp, sp, -16  # Adjust stack pointer (save more registers)
  sw ra, 12(sp)    # Save return address
  sw s0,  8(sp)    # Save s0
  sw s1,  4(sp)    # for s1

  # Load argument
  mv a1, a0        # Move size to a1

  # Allocate memory using sbrk
  li a7, 214        # sbrk syscall number
  ecall             # Call sbrk

  # Check return value
  bltz a0, error   # Jump to error handler if memory allocation failed

  # Update FREE_LIST
  lw s0, FREE_LIST   # Load FREE_LIST pointer
  sw a0, 0(s0)      # Store new memory address in FREE_LIST
  addi FREE_LIST, FREE_LIST, 4   # Update FREE_LIST pointer

  # Epilogue
  lw s1,  4(sp)    # Restore s1
  lw s0,  8(sp)    # for s1
  lw ra, 12(sp)    # Restore return address
  addi sp, sp, 16  # for stack pointer
  ret             # Return

error:
  # Handle memory allocation error here (e.g., set errno)
  .word 0  # Replace with actual error handling code
  mv a0, -1     # Return -1 to indicate error
  ret             # Return 

   .text
free:
  # Prologue
  addi sp, sp, -16  # Adjust stack pointer (save more registers)
  sw ra, 12(sp)    # Save return address
  sw s0,  8(sp)    # Save s0
  sw s1,  4(sp)    # Save s1

  # Load argument
  mv a0, a0        # Assuming pointer to be freed is passed in a0

  # Check if pointer is null
  beqz a0, exit    # Exit if pointer is null (nothing to free)

  # Update FREE_LIST
  lw s0, 0(a0)     # Load next free memory address
  sw s0, FREE_LIST   # Store next free memory address in FREE_LIST
  addi FREE_LIST, FREE_LIST, 4   # Update FREE_LIST pointer

  # Mark memory block as free
  sw 0, 0(a0)      # Write 0 to the first word to indicate free block

  # Epilogue
  lw s1,  4(sp)    # Restore s1
  lw s0,  8(sp)    # Restore s0
  lw ra, 12(sp)    # Restore return address
  addi sp, sp, 16  # Restore stack pointer
  ret             # Return

exit:
  # Nothing to do, just return
  ret             # Return from function
  
  
## Question 3

#include <iostream>
using namespace std;
int main() {
    int n;
    cout<<"enter value for n ";
    cin>>n;
    int a[n];
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    int b[n];
    for(int i=0;i<n;i++){
        if(i%2!=0 && i<=n-1){
            b[i]=a[(n/2)+(i-1)/2];
        }
        if(i==0){
            b[i]=a[i];
        }
        if(i%2==0 && i!=0 && i<=n-2){
            b[i]=a[i/2];
        }
    }
    for(int i=0;i<n;i++){
        cout<<b[i]<<" ";
    }
    return 0;
}