Reputation: 39
An assembly language program to convert a temperature value given in Fahrenheit to Celsius. The formula to be implemented is 𝐶 = (𝐹 − 32) × 5⁄9. Data Segments Required:
The stack is to be used for passing the Fahrenheit value to the subroutine and for returning the calculated Celsius value back to the main program. Dynamic stack allocation is to be implemented for this. Both the Fahrenheit and the calculated Celsius values are to be stored in the allocated memory locations defined in the data segment.
What I have so far is this code. When I run the program it says
Assemble: operation completed successfully.
It is supposed to ask the user to enter a Fahrenheit temperature. But it not doing that. Also, after the user enters a number, it should convert it to Celsius and display the result.
.data
F_temp: .word 0
C_temp: .word 0
Number1: .byte 32
number2: .byte 5
number3: .byte 9
enterNumber: .ascii "\nEnter a temperature in Fahrenheit: \n"
celsiusDegree: .ascii "\nCelsius temperature is: "
array: .word 0:25
welcome1: .ascii " \n This program converts Fahrenheit to Celsius \n\n"
.text
main:
la a0, welcome1 #display welcome message
li x0, 4
ecall
la x10,enterNumber #Ask user to write a number
li x17,4
ecall
la x6,array #store numbers array
li x30,25 #maximum of 25 integers are allowed to be entered
# F is in x10 #(F-32) * 5 / 9
addi x1, x0, 9 #t1 = 9
addi x2, x2, 5 #t0 = 5
addi s0, s0, 32 #s0 = 32
sub x10, x6, s0 #F-32
mul x10, x6, s0
div t0, t1, s0
done:
la x10,celsiusDegree #display celcius degree
ecall
exit:
ori a7, zero, 10 # define program exit system call
ecall # exit program
Upvotes: 0
Views: 3625
Reputation: 365257
x0
is hard-wired to 0
. It never makes sense to li
into it. https://en.wikichip.org/wiki/risc-v/registers.
Whatever register the ecall
handler looks in for a system-call number, it's not x0
. Check the documentation for whatever you're using. (e.g. RARS system-calls use a7
, the same way that MARS used the MIPS register $v0
(not MIPS $0
, the zero register))
Also generally a bad idea to mix x1
and t0
/ s0
register names. Easy to accidentally use 2 different names for the same register and have your code overwrite its own data.
In a previous version of the question you had:
Note: RISC-V multiply and divide instructions do not support immediates (constants). Therefore, all numeric values are to be defined in and loaded from memory
That's weird, the "therefore" doesn't really follow.
li reg, constant
is still cheaper than lw
, especially for a small integer. But if your assignment said you had to do it the stupid way, with data memory instead of foo = 5
or .equ
assemble-time symbolic constants, then you have to. You can define your constants in one place, but then still use them as immediates, if your assembler doesn't suck.
Upvotes: 2