calculator/calc.s

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