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.