Search code examples
arraysassemblyriscvin-place

I want to write an RISC-V assembly code that removes zeros from the given array and stores in the same exact memory address


I want to remove zero numbers from the given array that contains a sequence of numbers terminated with last element -1. For example:

arr2: .word 0 0 2 0 0 -1 ====> arr: .word 2 -1
arr: .word 0 3 0 0 3 0 3 0 -1 ====> arr: .word 3 3 3 -1

I tried writing this code:

.data
arr: .word 0 0 2 0 0 -1
.macro print_int (%x)
li a7, 1
mv a0, %x
ecall
.end_macro
.text
MAIN: #load array address to t0 to start and inizialize t3 to check if element is -1
li t3, -1
la t0, arr
loop:
# load first element of array and if it is zero replace current 0 with next array element and  
# move to check next element if the element is -1 go to print and print the array
lw t1, 0(t0)
beq t1, t3 print
addi t0, t0, 4
bnez t1, loop
lw t2, 4(t0)
mv t1, t2
sw t1, 0(t0)
j loop
print: #print the modified array
la t1, arr
printloop:
lw t2, 0(t1)
print_int (t2)
addi t1, t1, 4
beq t2, t3, exit
j printloop


exit:
li a7, 10
ecall

Edit: I wrote C++ code for this:

#include <iostream>

int main() {
  int arr[6] = {0, 0, 2, 0, 0, -1};
  int arr_temp[6];
  int final_index = 0;
  for (int i = 0, j = 0; i < 6; ++i) {
    if (arr[i] != 0) {
      arr_temp[j++] = arr[i];
    }
  }
  for (int i = 0; i < 6; ++i) {
    if (arr_temp[i] == -1) {
      final_index = i + 1;
    }
  }
  for (int i = 0; i < final_index; ++i) {
    arr[i] = arr_temp[i];
  }
  for (int i = 0; i < final_index; ++i) {
    std::cout << " " << arr[i] << " ";
  }
}

and i get this output in the console:

0220-1

instead of this:

2-1

Any ideas on how to solve this problem?


Solution

  • I think I have solved the problem thanks to the comments, i tried to write c++ code and then write that code in assembly and i came to this code and it finally worked as i wanted:

    .data
    arr: .word 0 0 2 0 0 -1
    arrtemp: .space 24
    msg: .string " "
    .macro print_str (%x)
    li a7, 4
    la a0, %x
    ecall
    .end_macro
    .macro print_int (%x)
    li a7, 1
    mv a0, %x
    ecall
    .end_macro
    .text
    MAIN:
    li t3, -1
    la t0, arr # load source array
    la t1, arrtemp # load auxilary array
    li t4, 6 # array size
    li s0, 0
    
    
    loop: # add non zero elements from source array to auxilary array 
    lw t5, 0(t0) 
    beq s0, t4, replace
    beqz t5, addjump
    lw t6, 0(t1)
    mv t6, t5
    sw t6, 0(t1)
    addi t0,t0,4
    addi s0, s0, 1
    addi t1, t1, 4
    j loop
    addjump:
    addi t0, t0, 4
    addi s0, s0, 1
    j loop
    
    
    
    replace: # overwrite source array with auxilary array
    la t0, arr
    la t1, arrtemp
    li t2, -1
    replaceloop:
    lw s0, 0(t1)
    sw s0, 0(t0)
    addi t1, t1, 4
    addi t0, t0, 4
    beq t2, s0, print
    j replaceloop
    
    
    print: # print modified source array
    li t3, -1
    la t0, arr2
    printloop:
    lw t1, 0(t0)
    print_int(t1)
    addi t0, t0, 4
    beq t1, t3, exit
    j printloop
    
    
    exit:
    li a7, 10
    ecall