110 lines
2.8 KiB
ArmAsm
110 lines
2.8 KiB
ArmAsm
# RISC-V assembly program implementing a calculator.
|
|
|
|
.org 0
|
|
# Provide program starting address to linker
|
|
.global _start
|
|
|
|
/* newlib system calls */
|
|
.set SYSEXIT, 93
|
|
.set SYSWRITE, 64
|
|
|
|
.section .rodata
|
|
str: .ascii "Hello World!\n"
|
|
.set str_size, .-str
|
|
str2: .ascii "regdump\n"
|
|
.set str2_size, .-str2
|
|
|
|
|
|
.section .bss
|
|
buf: .skip 20 # room for 20 byte string
|
|
# x10: ABCDEFG\n is 23 chars
|
|
|
|
.section .data
|
|
buflen: .byte 0 # length of buf string
|
|
|
|
|
|
.text
|
|
_start:
|
|
li t1, 0
|
|
li t2, 5
|
|
|
|
# dummy test for jal instruction
|
|
.L1:
|
|
jal x0, .L2
|
|
.L2:
|
|
nop
|
|
|
|
loop:
|
|
beq t1, t2, end
|
|
|
|
li t0, SYSWRITE # "write" syscall
|
|
li a0, 1 # 1 = standard output (stdout)
|
|
la a1, str # load address of hello string
|
|
li a2, str_size # length of hello string
|
|
ecall # invoke syscall to print the string
|
|
addi t1, t1, 1
|
|
j loop
|
|
|
|
end:
|
|
# do some adding
|
|
li a0, 0x80000000 # 0.5
|
|
li a1, 1 # 1
|
|
li a2, 0x80000000 # 0.5
|
|
li a3, 1 # 1
|
|
jal add64
|
|
#add t1, a0, 0 # copy a0 to t0 as end with overwrite it
|
|
jal regdump
|
|
|
|
li t0, SYSEXIT # "exit" syscall
|
|
add a0, x0, 0 # Use 0 return code
|
|
ecall # invoke syscall to terminate the program
|
|
|
|
# 64-bit integer addition
|
|
# arguments:
|
|
# a0: x lower 32 bits
|
|
# a1: x upper 32 bits
|
|
# a2: y lower 32 bits
|
|
# a3: y upper 32 bits
|
|
# return:
|
|
# a0: x+y lower 32 bits
|
|
# a1: x+y upper 32 bits
|
|
#
|
|
add64:
|
|
add a0, a0, a2 # add lower 32 bits
|
|
add t0, a1, a3 # add upper 32 bits
|
|
sltu t1, a0, a2 # if lower 32-bit sum < a2 then set t1=1 (carry bit)
|
|
add a1, t0, t1 # upper 32 bits of answer (upper sum + carry bit)
|
|
ret
|
|
|
|
|
|
# Print values of all registers (in hex)
|
|
# write syscall uses t0, a0, a1, a2
|
|
regdump:
|
|
addi sp, sp, -16 # allocate stack space
|
|
sw a0, 12(sp) # save contents of a0
|
|
sw a1, 8(sp) # save contents of a0
|
|
sw a2, 4(sp) # save contents of a0
|
|
sw t0, 0(sp) # save contents of a0
|
|
|
|
li t0, SYSWRITE # "write" syscall
|
|
li a0, 1 # 1 = standard output (stdout)
|
|
la a1, str2 # load address of hello string
|
|
li a2, str2_size # length of other string
|
|
ecall # invoke syscall to print the string
|
|
|
|
# as a test load something into buf and print it
|
|
la a1, buf # load address of buf into a1
|
|
li a0, 'h
|
|
sb a0, 0(a1)
|
|
li a0, '\n
|
|
sb a0, 1(a1)
|
|
li a2, 2 # length of buf
|
|
|
|
li t0, SYSWRITE # "write" syscall
|
|
li a0, 1 # 1 = standard output (stdout)
|
|
# li a2, buflen # length of hello string
|
|
ecall # invoke syscall to print the string
|
|
|
|
addi sp, sp, 16 # deallocate stack space
|
|
ret
|
|
|