Reputation: 259
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#
Upvotes: 2
Views: 2508
Reputation: 58762
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
Upvotes: 3