assemblyriscv

simple adder array int value in RISC-V asm


Just summers value by value from int array using stack pointer + offset to store values to make regs free. I am highly opened to get suggestions about improvement of the code.

In within of investigation of RISC-V platform.


array:
    .word 1,4,5,3,2

size:
    .word 5

.text

.global _start

_start:
    addi sp, sp, -20
    
    la t1, array
    sw t1, 0(sp)    # array
    
    la t0, size
    lw t0, 0(t0)
    addi t0, t0, -1
    sw t0, 4(sp)    # loop size
    
    li t0, 0
    sw t0, 8(sp)    # loop counter

    lw t1, 0(t1)
    sw t1, 12(sp)   # first value of loop result
    
    call _comp
    
_comp:
    lw t0, 8(sp)
    lw t1, 4(sp)
    bne t0, t1, _sum_array
    
    li a0, 0    # 0 status
    li a7, 93   # exit
    ecall
    
_sum_array:
    lw t0, 0(sp)
    addi t0, t0, 4
    sw t0, 0(sp)
    
    lw t1, 0(t0)
    
    lw t2, 12(sp)
    add t2, t2, t1
    sw t2, 12(sp)
    
    lw t0, 8(sp)
    addi t0, t0, 1
    sw t0, 8(sp)
    
    call _comp

Solution

  • You don't need to call the next instruction:

        lw t1, 0(t1)
        sw t1, 12(sp)   # first value of loop result
        
        call _comp
        
    _comp:
        lw t0, 8(sp)
        lw t1, 4(sp)
    

    Just eliminate the call and allow the processor to flow from the sw to the lw naturally.


        lw t0, 8(sp)
        addi t0, t0, 1
        sw t0, 8(sp)
        
        call _comp
    

    Here should be using j instruction instead of the call instruction — note these are both pseudo instructions, but the former does not capture return address and the latter does — both are versions of the jal instruction.


    Should start the data section with a .data directive — as you put the data first, then also put .data as the first line.


    That code is using equality test for the loop and setting the loop count to size: - 1.  So, this will not work for the degenerate case of a size of 0 (which is a legitimate array size) — it loops 2^32 times instead!

    Similarly, this code is initializing the sum variable, 12(sp), with the first element of the list, which assumes the list length is >= 1, which is not necessarily the case, as a list of 0 length is legitimate.  The sum of the elements of a zero length list is arguably zero, rather than the value of an out-of-bounds access to the first element (as it doesn't exit for a zero length list).

    You can fix the zero length use case while also simplifying the code:

    Don't subtract 1 in initialization of the counter end value, and, don't preload the first element, instead set the initial value of the sum to 0.