When working in Assembly Language, you are not getting any short cuts in life. If you want to output a single integer you need to add 48 to it to turn it in to an ASCII numeric character and then output that single character with a system call to the Linux write syscall.
Things get more complicated when you want output a multi-digit integer. First you need to split the number in to individual characters by getting the modulus 10 of the number, add 48 and put that on a stack, then divide the number by 10 and repeat until there are no more digets left in the integer
Finally we pop each ascii number off the stack and send to stdout with a syscall. We loop this action until the stack is empty.
intout.s
# # Risc-V Assembler program to convert an integer to a string # and output the result to stdout. # # a0-a2 - parameters to linux function services # a7 - linux function number # .data stack: .space 1024 # Allocate space for stack newline: .asciz "\n" # Newline character .section .text .global _start # Provide program starting address to linker .align 2 _start: la sp, stack # set stack pointer la a4, stack # set address of stack to a4 li a2, 10 # load constant for division li a0, 147856790 # load integer to print convert_loop: rem a3, a0, a2 # get remainder addi a3, a3, 48 # convert to ascii sw a3, 0(sp) # store in stack addi sp, sp, -4 # decrement stack pointer div a0, a0, a2 # divide by 10 bnez a0, convert_loop # loop until a0 is zero addi a0, x0, 1 # 1 = StdOut addi sp, sp, 4 # increment stack pointer to point to the start of the string mv a1, sp # copy stack pointer to a1 sub a2, a4, sp # calculate length of string slli a2, a2, 2 # multiply length by 4 addi a7, x0, 64 # linux write system call ecall # Call linux to output the string addi a0, x0, 1 # 1 = StdOut la a1, newline # load address of helloworld addi a2, x0, 1 # length of our string addi a7, x0, 64 # linux write system call ecall # Call linux to output the string # Call linux to terminate the program # Exit the program cleanly li a7, 93 # Exit system call for RISC-V li a0, 0 # Exit status code ecall
Assemble and Run
as -mno-relax -o intout.o intout.s ld -o intout intout.o ./intout
Mission Accomplished
And there we have it, you have a printed an integer to stdout. Its feels like alot of code which in C is basically one line, but this is just a step on the journey to understanding RISC-V and getting to a position where you can take advantage of everything that RISC-V can offer.