Hello World Agian
Following on from the basic Hello World RISC-V Assemly language program, next we will add a couple of improvements.
We make the assumption that you are working on Linux with a teminal emulator that supports ANSI (such as the default one in Ubuntu).
Our improvements are as follows:
We will clear the screen.
We will output the message in the middle of the screen.
We will print the first line in blue and the second in red.
We will only output each line once the user presses the space bar followed by the enter key.
A default terminal size of 80 columns and 24 lines is assumed for this program.
hello.s
#
# RISC-V Assembler program to clear the screen and print "Hello World!"
# and "Hello Again!" to stdout upon pressing the space bar.
# We assume that the terminal supports ANSI escape sequences.
# We assume the terminal size is 80 columns by 24 rows by.
#
.global _start # Provide program starting address to linker
_start:
la a1, clear_screen # load address of clear screen escape sequence
addi a0, x0, 1 # 1 = StdOut
addi a2, x0, 4 # length of escape sequence
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
# Initialize counter
addi t0, x0, 0 # Initialize counter t0 to 0
wait_for_space:
# Read a character from stdin
addi a0, x0, 0 # 0 = StdIn
la a1, input_char # load address of input_char
addi a2, x0, 1 # read 1 byte
addi a7, x0, 63 # linux read system call
ecall # Call linux to read input
# Check if the character is space (ASCII 32)
lb t1, 0(a1) # Load the input character to t1
addi t2, x0, 32 # Load ASCII value of space to t2
beq t1, t2, process_space # If space, process
j wait_for_space # Otherwise, keep waiting
process_space:
# Increment counter
addi t0, t0, 1
# Check counter value
li t3, 1
beq t0, t3, print_hello_world
li t3, 2
beq t0, t3, print_hello_again
li t3, 3
beq t0, t3, exit_program
j wait_for_space # If counter not 1, 2, or 3, wait for next space
print_hello_world:
la a1, cursor_pos # load address of cursor position escape sequence
addi a0, x0, 1 # 1 = StdOut
addi a2, x0, 8 # length of escape sequence
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
la a1, colour_blue # load address of blue colour escape sequence
addi a0, x0, 1 # 1 = StdOut
addi a2, x0, 5 # length of escape sequence
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
addi a0, x0, 1 # 1 = StdOut
la a1, helloworld # load address of helloworld
addi a2, x0, 13 # length of our string
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
j wait_for_space # Wait for next space press
print_hello_again:
la a1, cursor_pos2 # load address of second cursor position escape sequence
addi a0, x0, 1 # 1 = StdOut
addi a2, x0, 8 # length of escape sequence
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
la a1, colour_red # load address of red colour escape sequence
addi a0, x0, 1 # 1 = StdOut
addi a2, x0, 5 # length of escape sequence
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
addi a0, x0, 1 # 1 = StdOut
la a1, helloagain # load address of helloagain
addi a2, x0, 13 # length of our string
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
j wait_for_space # Wait for next space press
exit_program:
la a1, cursor_pos3 # load address of third cursor position escape sequence
addi a0, x0, 1 # 1 = StdOut
addi a2, x0, 8 # length of escape sequence
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
la a1, colour_reset # load address of reset colour escape sequence
addi a0, x0, 1 # 1 = StdOut
addi a2, x0, 4 # length of escape sequence
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
addi a0, x0, 1 # 1 = StdOut
la a1, doreturn # load address of doreturn
addi a2, x0, 2 # length of our string
addi a7, x0, 64 # linux write system call
ecall # Call linux to output the string
addi a0, x0, 0 # Use 0 return code
addi a7, x0, 93 # Service command code 93 terminates
ecall # Call linux to terminate the program
.data
helloworld: .ascii "Hello World!\n"
helloagain: .ascii "Hello Again!\n"
doreturn: .ascii " \n"
clear_screen: .ascii "\033[2J"
cursor_pos: .ascii "\033[12;30H"
cursor_pos2: .ascii "\033[14;30H"
cursor_pos3: .ascii "\033[24;0H"
colour_red: .ascii "\033[31m"
colour_blue: .ascii "\033[34m"
colour_reset: .ascii "\033[0m"
input_char: .byte 0
Assemble and Run
as -mno-relax -o hello.o hello.s ld -o hello hello.o ./hello
Mission Accomplished
And there we have it, you now have a functioning RISC-V Hello World that takes a user input and places a colourful message in the middle of the terminal.