2
votes

I was asked to write a program in mips assembly language to perform some basic arithmetic such as converting a temperature in Celsius to Fahrenheit. I ended up receiving a poor grade on this assignment because I used pseudo-instructions. I was unaware that I was even using pseudo-instructions because it appears many tutorials online use them without much clarification.

Out of curiosity I was wondering if someone could explain how to convert pseudo-instructions into non-pseudo-instructions?

below is my working program with pseudo-instructions:

## convert temperature from celsius to fahrenheit
## F = (9*C/5)+32
.text
.globl main
main:             # execution starts here

la $a0,getCelsius # ask user for temperature in celcius
li $v0,4          # print message to console
syscall         

li $v0,5           # read integer from console
syscall         

mul $t0,$v0,9   # compute ($v0 * 9)
div $t0,$t0,5   # compute ($v0 * 9) / 5
addi $t0,$t0,32   # compute (($v0 * 9) / 5) + 32

la $a0,tempF       # print message to console
li $v0,4
syscall 

move $a0,$t0        # print result of (($v0 * 9) / 5) + 32
li $v0,1
syscall

li $v0,10         # Done
syscall     

.data
getCelsius: .asciiz "Enter celsius temperature: "
tempF:  .asciiz "Fahrenheit temperature = "

A friend of mine told me that the Spim simulator actually converts the pseuo-instructions automatically and displays it. He said to copy and paste it into note padd and make minor changes. I'm still confused.

this is what I ended up copying and modifying:

.text
.globl main
main:


lui $11, 0x1001 [getCelsius]    # la $a0,getCelsius ask user for temperature
in celcius#
ori $4, $11, 0 [getCelsius]
ori $2, $0, 4                   # li $v0,4          print message to console#
syscall                         # syscall         
ori $2, $0, 5                   # li $v0,5          read integer from console#
syscall                         # syscall         
ori $11, $0, 9                  # mul $t0,$v0,9     compute ($v0 * 9)#
mul $8, $2, $11
ori $11, $0, 5                  # div $t0,$t0,5     compute ($v0 * 9) / 5#
div $8, $11
mflo $8
addi $8, $8, 32                 # addi $t0,$t0,32   compute (($v0 * 9) / 5) + 32#
lui $11, 0x1001 [tempF]         # la $a0,tempF      print message to console#
ori $4, $11, 28 [tempF]
ori $2, $0, 4                   # li $v0,4
syscall                         # syscall 
addu $4, $0, $8                 # move $a0,$t0      print result of (($v0 * 9) / 5) + 32#
ori $2, $0, 1                   # li $v0,1
syscall                         # syscall
ori $2, $0, 10                  # li $v0,10         Done#
1

1 Answers

1
votes

If you don't have documentation for your assembler detailing the pseudoinstructions, you can always just disassemble the binary and see what real code you got. But beware, some disassemblers recognize the patterns and recreate the pseudoinstructions.

That said, some pseudoinstructions I can spot:

la/li $r, x => lui $r, %hi(x) + addiu/ori $r, $r, %lo(x) Because there is no place for a 32 bit immediate in the instruction, this loads the top 16 bits first (clearing the bottom 16) then adds the low 16 bits. If the top 16 bits are known to be zero, you can use addiu/ori $r, $0, x instead. See also this question.

move $r0, $r1 => addu/or $r0, $0, $r1