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.