#How this program works:
#we input 2 integers from user, n1 and n2, in the “Run I/O” window.
#then we print the result n1+n2
#the n1+n2 is calculated withion the sum function in code
Copyright By PowCoder代写 加微信 powcoder
#You can tinker with this script to better understand the ins and outs of RISCV assembly
#But do so ONLY after having fully understood how this code works!!!
.macro exit #macro to exit program
.end_macro
.macro print_str(%string1) #macro to print any string
la a0, %string1
.end_macro
.macro print_int (%x) #macro to print any integer or register
add a0, zero, %x
.end_macro
.macro read_int #macro to input integer in a0
.end_macro
.macro print_int(%t0) #macro to print any integer
addi a0, %t0,0
.end_macro
prompt1: .asciz “Enter first number n1 :”
prompt2: .asciz “Enter second number n2 :”
outputMsg: .asciz ” (n1) added to ”
outputMsg2: .asciz ” (n2) gives the result ”
newline: .asciz “\n” #this prints a newline
#In case you might want to print one
#we dont use it in this program
#——-End of .data section!———
#we are now in the section devoted to storing the actual lines of code in our program.
print_str(prompt1)
#a0 now contains user input n1
#before we might overwrite a0 , lets preserve n1 value in t0
addi t0, a0, 0
print_str(prompt2)
#a0 now contains user input n2
#put n2 value in t1 register
addi t1, a0, 0
#the addition of t1+t0 will occur in the sum(n1,n2) function
#this function accepts arguments n1,n2 in a0,a1 registers
#it returns n1+n2 in a0
#This is the ONLY info main knows about sum(n1,n2) function!
#Let’s load up a0,a1 with correct t0,t1 respectively!
addi a0, t0, 0
addi a1, t1, 0
#Before we pass a0,a1 as arguments, ask yourself this question:
#Do we care about the values of t0,t1?
#Anser, we do! We need to print n1,n2 later in I/O console!
#As per RISCV function convention, callee function (sum) has no responsibility towards prserving t0,t1
#So we need to preserve t0,t1 to stack
#make way for 2 doublewords in stack
addi sp, sp, -16
#send over t0,t1 values to stack for posterity
sd t0, 0(sp)
sd t1, 8(sp)
#Now are ready to call sum function!
#We have returned from sum with return value in a0
#We have no idea if sum manipulated t0,t1 values or not
#Ofcourse, here you can peek at sum function to verify this
#But in a program with say, a million functions, it is diffucult to keep track!
#So we stick to the RISCV function convention
#We assume the worst and reload t0,t1 with the preserved values
ld t0, 0(sp)
ld t1, 8(sp)
#reset stack pointer to original level
addi sp, sp, 16
#now we need to display the sentence:
#” n1 added to n2 gives the result (n1+n2)”
#so let’s get to it!
#before we use the macros, remember they will modify a0 quite a lot!
#so we need to transfer current a0 value someplace else!
addi t2, a0, 0
#output n1 value
print_int(t0)
# output outputMsg string
print_str(outputMsg)
#output n2 value
print_int(t1)
# output outputMsg2 string
print_str(outputMsg2)
#output n1+n2 value
print_int(t2)
exit #exit from main()
#function accepts arguments in a0,a1
#function computes a0+a1
#function returns result in a0
#in this function, we are not using any s registers.
#so we are not concerned with preserving them to stack before we change modify them
#also sum is a LEAF function;i.e. it does not itself call any other function
#so no need to preserve the return address (ra) as well
add a0 , a0, a1
#now let’s return to which ever function called us!
#——-End of .text section!———
#Now that you have read the code, assemble the code!
#Click Assemble (Wrench and screwdiver icon)
#If teh Run Buttom becomes green , assembly is successful
#Click on the Run button
#Voila, you have added 2 input integers through a function!
allocate_file_record_pointers:
#argument: a0 contains file size in bytes
# a1 contains starting address of file buffer (for lab4 overall, this will be 0xffff0000
# but your function MUST be able to work for any a1 argument value
#function allocates to starting memory location 0x10040000 the array of file record pointers
#(refer to lab4 documentation to precisely understand how this is arranged in memory)
# returns the number of records in file in a0 register
#IMPORTANT ASSUMPTION: we are dealing with a csv file in Windows OS
#So each record ends with “\r\n”
li t0, 44 # ‘,’ character
li t1, 10#’\n’ character
li t2, 0x10040000
add t3, a1, a0 #counter to keep track till EOF
lbu t4, 0(a1)
#if file is empty(the very first byte is 0) just do nothing and return
bnez t4, fileNotEmpty
fileNotEmpty:
#let’s take care of first record in buffer
sw a1, 0(t2)
#first record’s name address is now in 0x10040000
#now need to account for this record’s income address
#then we repeat this for the remaining records in file
#we will assume in csv format name is alwuays followed by income in a specific record
addi t2, t2, 4
addi a1, a1, 1
allocate_file_record_pointers_loop1:
lbu t4, 0(a1)
#if byte t4 in file buffer is ‘,'(t0), then next byte’s address is stored in array and then update t2 by 4
#if byte t4 in file buffer is ‘\n'(t1), then next byte’s address is stored in array and then update t2 by 4
#keep on doing either of above till you reach EOF
bne t4, t0, notaComma
addi t5, a1, 1
sw t5, 0(t2)
addi t2, t2, 4
notaComma:
bne t4, t1, notaCommaOrNewLine
addi t5, a1, 1
sw t5, 0(t2)
addi t2, t2, 4
#each newline marks the end of a record
addi a0, a0, 1
notaCommaOrNewLine:
#loop update
addi a1, a1, 1
blt a1, t3, allocate_file_record_pointers_loop1
#through the loop’s algorithm above, we saved the EOF null byte location to array st 0x10040000 as well!
#need to reset that value of that array entry to zero!
addi t2, t2, -4
sw t0, 0(t2)
#######################end of allocate_file_record_pointers###############################################
income_from_record:
#function to return numerical income from a specific record
#e.g. for record “Microsoft,34\r\n”, income to return is 34(for which name is Microsoft)
#arguments: a0 contains pointer to start of numerical income in record
#function RETURNS income numerical value of the asci income in a0 (34 in our example)
# Start your coding from here!
#if no student code entered, a0 just returns 0 always 🙁
# End your coding here!
#######################end of income_from_record###############################################
#address of file buffer: 0xffff0000 (MMIO)
#address of file record pointers(for location of starting points of stock name and income): 0x10040000 (heap)
#URGENT: make sure your csv file follows the Windows csv format:
#e.g. “Facebook,56\r\nApple,100\r\n”
.macro print_str(%str)
la a0, %str
.end_macro
.macro print_character(%charRegister)
addi a0, %charRegister, 0
.end_macro
.macro print_Int(%IntRegister)
addi a0, %IntRegister, 0
.end_macro
.macro file_open_for_read(%str)
la a0, %str
li a7, 1024
.end_macro
.macro fileRead(%file_descriptor_register, %file_buffer_address)
#macro reads upto first 10,000 characters from file
addi a0, %file_descriptor_register, 0
li a1, %file_buffer_address
li a2, 10000
.end_macro
.macro print_file_contents(%ptr_register)
addi a0, %ptr_register, 0
#entire file content is essentially stored as a string
.end_macro
.macro close_file(%file_descriptor_register)
addi a0, %file_descriptor_register, 0
.end_macro
.macro exit
.end_macro
filePath: .asciz “data.csv”
fileBeginPrompt: .asciz “Printing file contents…\n________________________\n”
fileEndPrompt: .asciz “________________________\n”
msg: .asciz “Size of file data (in bytes): ”
totalPrompt: .asciz “Total income garnered from all stocks: $”
maxPrompt: .asciz “Stock name with maximum income:”
newline: .asciz ” \n”
#open file as read
file_open_for_read(filePath)
#a0 has file descriptor (identifuer #).Copy it to t0
addi t0, a0, 0
#read from file
fileRead(a0, 0x0ffff0000)
#print text stored at pointer from a1.a1 currently holds 0xffff0000
print_str(fileBeginPrompt)
print_file_contents(a1)
print_str(fileEndPrompt)
#find length of file
print_str(msg)
addi a0, t0, 0
addi t1, t0, 0#safekeeping file descriptor value in t1
addi sp, sp, -4
sw t1, 0(sp)
jal length_of_file
lwu t1, 0(sp)
addi sp, sp, 4
print_Int(a0)
addi t0, a0, 0
print_str(newline)
addi a0, t0, 0
#allocate file record pointers into memory at 0x10040000
addi sp, sp, -4
sw t1, 0(sp)
#a0 currently contains size of file in bytes
#IMPORTANT NOTE: if you have not correctly implemented length_of_file.asm yet, please set a0 to 119 at this point
#this is to ensure allocate_file_record_pointers function works independently of length_of_file.asm
li a0, 119
#Comment out the line above so that you can test your code for different data in data.csv!!!!!
li a1, 0x0ffff0000
jal allocate_file_record_pointers
lwu t1, 0(sp)
addi sp, sp, 4
addi t6, a0, 0 #t6=no. of records in file
#test total income
print_str(totalPrompt)
li a0, 0x10040000
addi a1, t6, 0#no. of records in file
addi sp, sp, -4
sw t6, 0(sp)
jal totalIncome
lwu t6, 0(sp)
addi sp, sp, 4
print_Int(a0)
print_str(newline)
#test stock with max income
print_str(maxPrompt)
li a0, 0x10040000
addi a1, t6, 0#no. of records in file
jal maxIncome
#a0 contains pointer to address that is start of stock name from pointer table
#a0+4 then points to address that is start of stock income in original file
addi t0, a0, 0
addi t1, a0, 4
lwu t0, 0(t0)
lwu t1, 0(t1)
addi t1, t1, -1
# t1 now contains address of last character in stock name
printmaxIncomeloop:
beq t0, t1, printmaxIncomeloopExit
lbu t2, 0( t0)
#loading byte at address in t0 into t2
print_character(t2)
printmaxIncomeloopUpdate:
addi t0, t0, 1
j printmaxIncomeloop
printmaxIncomeloopExit:
#######################end of main###############################################
.include “allocate_file_record_pointers.asm”
.include “income_from_record.asm”
.include “length_of_file.asm”
.include “totalIncome.asm”
.include “maxIncome.asm”
length_of_file:
#function to find length of data read from file
#arguments: a1=bufferAdress holding file data
#return file length in a0
#Start your coding here
#if no student code provided, this function just returns 0 in a0
#End your coding here
#######################end of length_of_file###############################################
maxIncome:
#finds the total income from the file
#arguments: a0 contains the file record pointer array location (0x10040000 in our example) But your code MUST handle any address value
# a1:the number of records in the file
#return value a0: heap memory pointer to actual location of the record stock name in the file buffer
#if empty file, return 0 for both a0, a1
bnez a1, maxIncome_fileNotEmpty
maxIncome_fileNotEmpty:
# Start your coding from here!
li a0, 0x10040010
#if no student code entered, a0 just returns 0x10040010 always 🙁
# End your coding here!
#######################end of maxIncome###############################################
#How this program works:
#we input 2 integers from user, n1 and n2, in the “Run I/O” window.
#then we print the result n1*n2
#n1*n2 is done by the multiply function
#multiply function itself calls another function sum
#NOTE: This code ONLY works if n2>=0!
#If you input n2<0, you will always get 0 output!
#You can tinker with this script to better understand the ins and outs of RISCV assembly
#But do so ONLY after having fully understood how this code works!!!
.macro exit #macro to exit program
.end_macro
.macro print_str(%string1) #macro to print any string
la a0, %string1
.end_macro
.macro print_int (%x) #macro to print any integer or register
add a0, zero, %x
#zero here refers to register #0
#the zero register always has constant value of 0
.end_macro
.macro read_int #macro to input integer in a0
.end_macro
#later on, when we use functions in code, be VERY careful when creating macros!
#Macros might unintentionally change register values that can cause runtime errors
#as your code becomes dense, it becomes difficult to track the changing register values
#we are now in the data section of memory.
prompt1: .asciz "Enter first number n1 :"
prompt2: .asciz "Enter second number n2 :"
outputMsg: .asciz " (n1) multiplied with "
outputMsg2: .asciz " (n2) gives the result "
newline: .asciz "\n" #this prints a newline
#In case you might want to print one
#we dont use it in this program
#-------End of .data section!---------
#we are now in the section devoted to storing the actual lines of code in our program.
main: # Label to define the main program.
#print prompt1 string on console
print_str(prompt1)
#set t0->n1
addi t0, a0, 0
#print prompt2 string on console
print_str(prompt2)
#set t1->n2
addi t1, a0, 0
#t1*t2 will occur in the multiply(n1,n2) function
#this function accepts arguments n1,n2 in a0,a1 registers
#it returns n1*n2 in a0
#This is the ONLY info main knows about multiply(n1,n2) function!
#Let’s load up a0,a1 with correct t0,t1 respectively!
addi a0, t0, 0
addi a1, t1, 0
#preserve t0,t1 to stack
addi sp, sp, -16
sd t0, 0(sp)
sd t1, 8(sp)
#Now are ready to call multiply function!
jal multiply
#We have no idea if sum manipulated t0,t1 values or not
#Ofcourse, here you can peek at sum function to verify this
#But in a program with say, a million functions, it is diffucult to keep track!
#So we stick to the RISCV function convention
#We assume the worst and reload t0,t1 with the preserved values
ld t0, 0(sp)
ld t1, 8(sp)
#reset stack pointer to original level
addi sp, sp, 16
#now we need to display the sentence:
#” n1 added to n2 gives the result (n1+n2)”
#so let’s get to it!
#before we use the macros, remember they will modify a0 quite a lot!
#so we need to transfer current a0 value someplace else!
addi t2, a0, 0
#let’s print the result
print_int(t0)#n1
print_str(outputMsg)
print_int(t1)#n2
print_str(outputMsg2)
print_int(t2)#n1*n2
multiply: #ennter multiply function
#accepts a0 and a1 as arguments for n1,m2
#retrurns n1*n2 in a0
#multiply in our example is callee to main but is itself caller to sum funciton
#using sum function herely is purely for demonstrational purposes only
#in reality , we would not need to call a funciton just to add 2 numbers!
#in this function, we are not using any s registers.
#so we are not concerned with preserving them to stack before we change modify them
#however, we need to preserve ra
addi sp, sp, -8
sd ra, 0(sp)
#trasnsfer a0,a1 to t0,t1
addi t0,a0,0
addi t1,a1,0
#counter i=0
addi t3,zero,0
#result =0
addi t4,zero, 0
loop: beq t3,t1, loop_exit #exit loop when i=n2
#let’s call function sum to compute: t4+t0
#preserve t0,t1,t2,t3,t4 to stack as caller funciton
addi sp, sp, -40
sd t0, 0(sp)
sd t1, 8(sp)
sd t2, 16(sp)
sd t3, 24(sp)
sd t4, 32(sp)
#place arguments in a0,a1
addi a0, t4, 0
addi a1, t0, 0
#a0 returns with n1+n2
#restore stack values as caller
ld t0, 0(sp)
ld t1, 8(sp)
ld t2, 16(sp)
ld t3, 24(sp)
ld t4, 32(sp)
addi sp, sp, 40
#acumulate a0 in t4
addi t4, a0, 0
loop_update:
addi, t3,t3,1
loop_exit:
#restore ra fo the convenience of multiply’s caller
ld ra, 0(sp)
addi sp, sp, 8
#done with multiply function!
sum: #exact same function from add_function.asm
#function accepts arguments in a0,a1
#function computes a0+a1
#function returns result in a0
#in this function, we are not using any s registers.
#so we are not concerned with preserving them to stack before we change modify them
#also sum is a LEAF function;i.e. it does not itself call any other function
#so no need to preserve the return address (ra) as well
add a0 , a0, a1
#now let’s return to which ever function called us!
#——-End of .text section!———
totalIncome:
#finds the total income from the file
#arguments: a0 contains the file record pointer array location (0x10040000 in our example) But your code MUST handle any address value
# a1:the number of records in the file
#return value a0:the total income (add up all the record incomes)
#if empty file, return 0 for a0
bnez a1, totalIncome_fileNotEmpty
totalIncome_fileNotEmpty:
# Start your coding from here!
#if no student code entered, a0 just returns 0 always 🙁
# End your coding here!
#######################end of nameOfMaxIncome_totalIncome###############################################
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com