如何转换Mips伪指令?

时间:2015-02-08 00:10:52

标签: assembly mips spim qtspim

我被要求用mips汇编语言编写程序来执行一些基本算法,例如将摄氏温度转换为华氏温度。因为我使用了伪指令,所以我最终得到了这个作业的低分。我不知道我甚至使用伪指令,因为看起来很多教程在线使用它们而没有太多的澄清。

出于好奇,我想知道是否有人可以解释如何将伪指令转换为非伪指令?

下面是我的伪指令工作程序:

## 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 = "

我的一位朋友告诉我,Spim模拟器实际上会自动转换pseuo指令并显示它。他说将其复制并粘贴到记事本中并进行微小的更改。我还是很困惑。

这是我最终复制和修改的内容:

.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 个答案:

答案 0 :(得分:1)

如果您没有详细说明伪指令的汇编程序的文档,您可以随时反汇编二进制文件并查看您获得的实际代码。但要注意,一些反汇编程序会识别模式并重新创建伪指令。

那就是说,我可以发现一些伪指令:

la/li $r, x => lui $r, %hi(x) + addiu/ori $r, $r, %lo(x)因为指令中没有32位立即数的位置,所以首先加载前16位(清除底部16位)然后加上低16位。如果已知前16位为零,则可以使用addiu/ori $r, $0, x代替。另请参阅this question

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