Emiliano Martinez
Emiliano Martinez

Reputation: 9

An assembly procedure to convert a temperature in Fahrenheit to Celsius

I keep getting this error on my code:

spim: (parser) syntax error on line 62 of file C:/Users/Emili/Downloads/Hello World.s ldc1 $f2, 32.0

.data
prompt: .asciiz "Enter temperature in Fahrenheit: "
result: .asciiz "The temperature in Celsius is: "
prompt2: .asciiz "Convert another temperature? (y/n): "
newline: .asciiz "\n"

.text
.globl main
.ent main

main:
    # Print prompt and read Fahrenheit temperature
    li $v0, 4
    la $a0, prompt
    syscall

    li $v0, 5
    syscall
    move $t0, $v0  # Save Fahrenheit temperature in $t0

    # Call conversion procedure
    jal convertToFahrenheit

    # Print the Celsius temperature
    li $v0, 4
    la $a0, result
    syscall

    li $v0, 2
    mov.s $f12, $f0  # Move Celsius temperature to $f12
    syscall

    # Ask if user wants another conversion
    li $v0, 4
    la $a0, prompt2
    syscall

    li $v0, 12
    syscall
    move $t1, $v0  # Save user's input in $t1

    # Check if input is 'y'
    li $t2, 'y'
    bne $t1, $t2, exit  # Exit program if input is not 'y'

    # Print newline
    li $v0, 4
    la $a0, newline
    syscall

    j main  # Start another iteration of the program

exit:
    # Program is finished running
    li $v0, 10
    syscall
.end main

# Conversion procedure
convertToFahrenheit:
    sub.s $f0, $f12, $f0
    ldc1 $f2, 32.0
    sub.s $f0, $f0, $f2
    ldc1 $f2, 9.0
    div.s $f0, $f0, $f2
    mul.s $f0, $f0, $f2
    jr $ra

Upvotes: 0

Views: 74

Answers (1)

Erik Eidt
Erik Eidt

Reputation: 26656

All the 2nd operands for ldc1 and l.d (same, but IMHO preferable) are memory locations, usually specified as simple labels to data or an addressing mode relative to an integer base register.

While integer instructions allow for a li pseudo instruction, these (e.g. l.d) are not the equivalent of that for floating point — these are the equivalent of lw for the integer unit.

If all you had was lw how might you get a particular integer constant into an integer register?  Load it from memory, of course, and give lw the name of the label you'd used for that data item.

Same idea for floating point constants.  Floating point constants are 32-bits for single or 64-bits for double, so don't fit well into the instruction stream anyway, might as well load from memory.

Btw, also applies to string literals — la doesn't allow you to put a string literal directly as the 2nd argument, so have to declare strings initialized in memory and then reference them using a label or something.


Looks like you're accidentally mixing single float and double float, so maybe check on that.  If you really wanted to mix them, you have to convert from single to double and/or vice versa — can't just add double to single directly (or vice versa).


(Suggest using l.s for single and l.d for double rather than lwc1 and ldc1 — the .s and .d suffix will help remind you what precision you're using as it looks similar to add.s and mul.s)

Upvotes: 1

Related Questions