We start with simple examples of simple sequences of instructions
      register to register
  addi x2,x0,11
          add  x3,x2,x0
      
      register to/from memory
  addi x5,x0,0x11        #
        set x5 to 0x11
          sw x5, 0x100(x0)       # store at
        address 0x100
          lw x6, 0x100(x0)       # get from
        mem
          addi
        x6,x6,1           
          sw x6, 0x104(x0)       # store to
        mem 0x104
  a = b + c
       
      local variables are stored in registers
        let x4 - a, x5 -b, x6 - c
      
        add x4, x5, x6
      
      global variables are stored in memory
        let M[100] - a, M[104] - b, M[108] - c
        let x4 - a, x5 - b, x6 - c
      
      must move data from memory to register before perform addition
      
        lw  x5, 0x104(x0)     # get b
          lw  x6, 0x108(x0)     # get c
          add x4, x5, x6
          sw  x4, 0x100(x0)     # store to a
using offset,  base address points to the beginning of the array
      
         ax[10]    ax starts at 0x100  base
      address
      
         to get an element at ax[1]
         let x3 - index, x4 - base, x5 - effective address, x5 - value
      
         addi
        x3,x0,1         # index
           addi x4,x0,0x100     # base
           add 
        x5,x3,x4        # compute effective
        address
           lw  
        x6,0(x5)        # get from memory
while condition
         body
is transformed into sequences of instructions
loop:
        test condition
        jump if false to exit
        body
        jump loop 
      exit:
example
i = 0
        while i < 10
          i = i + 1
      
      let x3 - i
      
         addi x3,x0,0    # i = 0
           addi x4,x0,10   # const 10
        loop:
           bge  x3,x4, exit
           addi x3,x3,1
           j loop
        exit:
sum all elements of an array
pseudo code
ax[5]
        
        s = 0
        i = 0
        while i < 5
          s = s + ax[i]
          i = i + 1
let x3 - s, x4 - i, x5 - const 5, x6 - base, x7 - effective address, 
      x8 - offset, x9 - ax[i]
      
        addi x3,x0,0       #  s =
        0
          addi x4,x0,0       #  i = 0
          addi x5,x0,5       #  const 5
          addi x6,x0,0x100   #  base address of ax[]
          addi x8,x0,0       #  offset =
        0
        loop:
          bge x4, x5, exit
          add x7, x6, x8    # compute effective address 
          lw  x9, 0(x7)     # get ax[i]
          add x3, x3, x9    # s = s + ax[i]
          addi x8, x8, 4    # next element
          addi x4, x4, 1    # increment index
          j loop
        exit:
      use "godbolt.org" (Compiler
      Explorer)  with "RISC_V ricv32gc" compiler
      
      the first simple program (C)
      
      int a,b,c;
        
        int main(){
          a = 11;
        }
      
      risc-v assembly output, we put a at address 0x100
      
        li     a1, 0x0100
          li     a0, 11
          sw     a0, 0(a1)
      
      second program: if then else
      
      int a,b,c;
        
        int main(){
          if(a > 0){
            b = 22;
          }
        }
      
      risc-v assembly output, a at 0x100, b at 0x104
      
         li     a1, 0x100
           lw     a1, 0(a1)
           bge    a0, a1, LBB0_2
           li     a1, 0x104
           li     a0, 22
           sw     a0, 0(a1)
        LBB0_2:
      
      call a function
      
      to perform a "jump" to subroutine, we need a way to "come back" to where
      we call.
      use a register to store "return address"
int twice(int x){
        return( x + x);
      }
      
      int main(){
        int a;  
        a = twice(2);
      } j main
       twice:                             
      # @twice
              addi    sp, sp,
      -16          # create stack
      frame with 4 slots
             
      sw      ra,
      12(sp)           # first
      slot keeps return address
             
      sw      s0,
      8(sp)            #
      second slot keeps s0
              addi    s0, sp,
      16           # set s0 to
      this stack frame
             
      sw      a0,
      -12(s0)          # store
      passing value (x) to slot 4
             
      lw      a0,
      -12(s0)          # get x
              add     a0,
      a0, a0           # x +
      x   return value in a0
             
      lw      ra,
      12(sp)           #
      restore return address 
             
      lw      s0,
      8(sp)            
              addi    sp, sp,
      16           # delete
      stack frame
              ret
      main:                                
      # @main
              addi    sp, sp,
      -16           # stack
      frame has 4 slots
             
      sw      ra,
      12(sp)            
             
      sw      s0,
      8(sp)                     
      
        addi    s0,
      sp, 16
             
      li      a0,
      2                
      # pass number 2 in a0
              call   
      twice                
      # call twice
             
      sw      a0,
      -12(s0)           # put
      return value to a
             
      li      a0, 0
             
      lw      ra,
      12(sp)            
      
             
      lw      s0,
      8(sp)            
      
              addi    sp, sp,
      16            #
      restore spstack frame
sp -> 1) return address   <- s0
            2) old s0
            3) ...
            4) x
      sp' ->end
last update 31 Jan 2022