Here is a list of example Assembly langauge programs developed by Stephen Marz. You can look at the complete examples on his website here
Find String Length in RISC-V Assembly
First we write the program in plain C
int strlen(const char *str) { int i; for (i = 0;str[i] != '\0';i++); return i; }
Here is the corresponding RISC-V Assembly
.section .text .global strlen strlen: # a0 = const char *str add t0, zero, zero # i = 0 1: # Start of for loop add t1, t0, a0 # Add the byte offset for str[i] lb t1, 0(t1) # Dereference str[i] beq t1, zero, 1f # if str[i] == 0, break for loop addi t0, t0, 1 # Add 1 to our iterator jal zero, 1b # Jump back to condition (1 backwards) 1: # End of for loop addi a0, t0, 0 # Move t0 into a0 to return jalr zero, ra # Return back via the return address register
String Copy in RISC-V Assembly
First we write the program in plain C
void stringcopy(char *dst, const char *src) { do { // Copy the source's byte into the destination's byte *dst = *src; // We check '\0' here so that we copy the source's \0 // into the destination. if (*src == '\0') break; // Advance both the destination and source to the next byte. dst++; src++; } while (true); }
Here is the corresponding RISC-V Assembly
.section .text .global stringcopy stringcopy: # a0 = destination # a1 = source 1: lb t0, 0(a1) # Load a char from the src sb t0, 0(a0) # Store the value of the src beq t0, zero, 1f # Check if it's 0 addi a0, a0, 1 # Advance destination one byte addi a1, a1, 1 # Advance source one byte jal zero, 1b # Go back to the start of the loop 1: jalr zero, 0(ra) # Return back via the return address
Reverse a string in RISC-V Assembly
First we write the program in plain C
void strrev(char *str) { int i; int sz = strlen(str); for (i = 0;i < sz / 2;i++) { char c = str[i]; str[i] = str[sz - i - 1]; str[sz - i - 1] = c; } }
Here is the corresponding RISC-V Assembly
.section .text .global strrev strrev: # s1 = str # a0 = sz # t0 = sz / 2 # t1 = i # Enter stack frame addi sp, sp, -16 sd ra, 0(sp) sd s1, 8(sp) # Get the size of the string mv s1, a0 call strlen srai t0, a0, 1 # Divide sz by 2 li t1, 0 # i = 0 1: # for loop bge t1, t0, 1f add t2, s1, t1 # str + i sub t3, a0, t1 # sz - i addi t3, t3, -1 # sz - i - 1 add t3, t3, s1 # str + sz - i - 1 lb t4, 0(t2) # str[i] lb t5, 0(t3) # str[sz - i - 1] sb t4, 0(t3) # swap sb t5, 0(t2) addi t1, t1, 1 j 1b 1: # Leave stack frame ld s1, 8(sp) ld ra, 0(sp) addi sp, sp, 16 ret
Bubblesort in RISC-V Assembly
First we write the program in plain C
void bubsort(long *list, int size) { bool swapped; do { swapped = false; for (int i = 1;i < size;i++) { if (list[i-1] > list[i]) { swapped = true; long tmp = list[i-1]; list[i-1] = list[i]; list[i] = tmp; } } } while (swapped); }
Here is the corresponding RISC-V Assembly
.section .text .global bubsort bubsort: # a0 = long *list # a1 = size # t0 = swapped # t1 = i 1: # do loop addi t0, zero, 0 # swapped = false addi t1, zero, 1 # i = 1 2: # for loop bge t1, a1, 2f # break if i >= size slli t3, t1, 3 # scale i by 8 (for long) add t3, a0, t3 # new scaled memory address ld t4, -8(t3) # load list[i-1] into t4 ld t5, 0(t3) # load list[i] into t5 ble t4, t5, 3f # if list[i-1] < list[i], it's in position # if we get here, we need to swap addi t0, zero, 1 # swapped = true sd t4, 0(t3) # list[i] = list[i-1] sd t5, -8(t3) # list[i-1] = list[i] 3: # bottom of for loop body addi t1, t1, 1 # i++ jal zero, 2b # loop again 2: # bottom of do loop body bne t0, zero, 1b # loop if swapped = true jalr zero, 0(ra) # return via return address register
Leave A Comment
You must be logged in to post a comment.