# Lab1: R32I Simulator ### Pow Function In this assignment, I impliment the pow function in RISC-V assembly language. Let's take a look at the syntax for the pow function in the C Language. ``` double pow(double x, double y); ``` Where the pow function `returns x raised to the power of y.` The complete implementation in RISC-V code contains following sections: #### *data section* --- contains arguments for function and needed string sentences. ``` .data argument1: .word 5 # base number in pow function argument2: .word 3 # power number in pow function str1: .string " raised to the power of " str2: .string " is " ``` #### *text section* --- where all the instructions lie in. And I will describe the functionality of each subpart in this section. > main Acts as the same role in C programs, in charge of the main control flow of this program. ``` .text main: # Load arguments from static data lw a0, argument1 lw a1, argument2 # Jump-and-link to the 'pow' label jal ra, pow # Print the result to console add a2, a0, zero lw a0, argument1 lw a1, argument2 jal ra, printResult #Exit program li a0, 10 ecall ``` Now I will take an instruction as an example to explain their journey inside the cpu. --- When the program starts to execute, cpu begins to fetch instructions from the instruction memory, and the very first instruction enters IF stage. ![](https://i.imgur.com/kG6L44K.png) We can see from the image that the first insturction`auipc x10 65536` is in the IF stage. --- And a cycle later, it enters the decode stage ID to let cpu know what is the exact operation this instruction wants to do. ![](https://i.imgur.com/qNOa1sa.png) Notice that at the same time, the second instruction `lw x10 0(x10)` enters IF stage, illustrates the 'pipe' characteristic in cpu architecture implementation. These two instructions are from the `lw a0, argument1` instruction in our RISC-V code, which will load the argument into the `a0` register for further accessing by multiplixer. --- Two more cycles later, the second instruction enters the execution IE stage, ready to give out the couputation result. As we mentioned above, these two instruction are for load operation, hence when it finally enters MEM stage, we can see the `Read` port on the simulator turns into green light. ![](https://i.imgur.com/MfqShsw.png) One more cycle later, it enters the final WB stage, write the data read from data memory into the target register, officially complete the job as an instruction. ![](https://i.imgur.com/Bn9Z2uZ.png) --- > pow First part of the pow function, in charge of creating and initializing local variable and make sure the values used by callee are saved properly. ``` pow: # Save original register value addi sp, sp, -8 sw ra, 4(sp) sw s0, 0(sp) addi s0, zero, 1 # initialize result addi t2, zero, 1 # restric loop time bne a1, zero, loop ret ``` > loop Second part of the pow function, in charge of the count down in power. ``` # base loop multiplies itself loop: mv t0, a0 mv t1, s0 jal ra, multiplyBase addi a1, a1, -1 bne a1, zero, loop # restore return address mv a0, s0 lw s0, 0(sp) lw ra, 4(sp) addi sp, sp, 8 ret ``` > multiplyBase Third part of the pow function, in charge of the muplitication. ``` multiplyBase: add s0, s0, t1 addi t0, t0, -1 bne t0, t2, multiplyBase ret ``` > printResult Print out the computation result. ``` # expects: # a0: Value of base number # a1: Value of power number # a2: power of base result printResult: mv t0, a0 mv t1, a1 mv t2, a2 add a1, t0, zero li a0, 1 ecall la a1, str1 li a0, 4 ecall add a1, t1, zero li a0, 1 ecall la a1, str2 li a0, 4 ecall add a1, t2, zero li a0, 1 ecall ret ```