Assembly QtSpim汇编程序:使用双精度

Assembly QtSpim汇编程序:使用双精度,assembly,double,mips,spim,qtspim,Assembly,Double,Mips,Spim,Qtspim,我正在为课堂写一个程序。它从控制台获取x和epsilon,并应检索sin(x)近似值。当我在QtSpim中运行它时,我得到错误: 未知的指令类型:0 错误发生在以下位置: floatsin: addi $sp, $sp, -64 # Frame sw $ra, 64($ra) sw $fp, 60($sp) s.d $f0, 56($sp)

我正在为课堂写一个程序。它从控制台获取x和epsilon,并应检索sin(x)近似值。当我在QtSpim中运行它时,我得到错误:

未知的指令类型:0

错误发生在以下位置:

 floatsin:    addi    $sp, $sp, -64   # Frame
              sw      $ra, 64($ra)
              sw      $fp, 60($sp)
              s.d     $f0, 56($sp)
              s.d     $f4, 48($sp)
              s.d     $f20, 40($sp)
              s.d     $f8, 32($sp)
              s.d     $f10, 24($sp)
              s.d     $f14, 16($sp)
              s.d     $f18, 8($sp)        # ERROR HERE
              addi    $fp, $sp, 64
原因可能是什么?我很困惑,因为直到
s.d$f18
一切正常。谢谢你的提示

以下是完整的程序:

.data
xinput:      .asciiz "\nPlease enter x\n"
epsinput:    .asciiz "\nPlease enter epsilon\n"
sinxoutput:  .asciiz "\nsin(x) is: "

.text

main: la    $a0, xinput
      li    $v0, 4
      syscall
      li    $v0, 7
      syscall
      mov.d $f2, $f12
      la $a0, epsinput
      li $v0, 4
      syscall
      li    $v0, 7
      syscall
      mov.d $f0, $f12
      jal   floatsin
      la    $a0, sinxoutput
      li    $v0, 4
      syscall
      li    $v0, 3
      syscall
      li    $v0, 10
      syscall

floatsin:     addi    $sp, $sp, -64   # Frame
              sw      $ra, 64($ra)
              sw      $fp, 60($sp)
              s.d     $f0, 56($sp)
              s.d     $f4, 48($sp)
              s.d     $f20, 40($sp)
              s.d     $f8, 32($sp)
              s.d     $f10, 24($sp)
              s.d     $f14, 16($sp)
              s.d     $f18, 8($sp)
              addi    $fp, $sp, 64

              li.d    $f8,  0.0   # Initialize
              li.d    $f14, 1.0
              mov.d   $f16, $f0
              li.d    $f18, 0.0

              jal     loop_p1

main_loop:    add.d   $f18, $f18, $f4
              c.lt.d  $f2, $f4
              bc1f    exit_fsin
              jal     loop_p1
              sub.d   $f18, $f18, $f4
              c.lt.d  $f2, $f4
              bc1f    exit_fsin
              jal     loop_p1
              j       main_loop


loop_p1:      add.d   $f8, $f8, $f14
              li.d    $f10, 1.0       #for (j < 2i-1)
              mov.d   $f4,  $f16
              li.d    $f20, 0.0
              add.d   $f20, $f8, $f8
              sub.d   $f20, $f20, $f14
for:          c.lt.d  $f10, $f20
              bc1f    loop_p2
              mul.d   $f4, $f4, $f16 # (x*x)
              add.d   $f10, $f10, $f14
              j       for

loop_p2:      mov.d   $f0, $f20
              move    $t0, $ra
              jal     floatfac
              div.d   $f4, $f4, $f12
              jr      $t0

exit_fsin:    mov.d   $f12, $f18     # Write in target register
              l.d     $f18, 8($sp)   # rewrite values
              l.d     $f14, 16($sp)
              l.d     $f10, 24($sp)
              l.d     $f8,  32($sp)
              l.d     $f20, 40($sp)
              l.d     $f4,  48($sp)
              l.d     $f0,  56($sp)
              lw      $fp,  60($sp)
              lw      $ra,  64($sp)
              addi    $sp, $sp, 64
              jr      $ra           # back to caller


floatfac:     addi    $sp, $sp, -28   # Frame
              sw      $fp, 28($sp)
              s.d     $f4, 24($sp)
              s.d     $f2, 16($sp)    
              s.d     $f0,  8($sp)
              addi    $fp, $sp, 28

              li.d    $f4, 0.0
              c.le.d  $f0, $f4
              bc1t    negative
              li.d    $f12, 1.0
              li.d    $f2, 1.0

while:        c.le.d  $f0, $f2       # Break condition
              bc1t    exit_floatfact
              mul.d  $f12, $f12, $f0
              sub.d   $f0, $f0, $f2
              j       while



negative:     li.d     $f12, 0.0




exit_floatfact: l.d      $f0,  8($sp)   # rewrite values
                l.d      $f2, 16($sp)
                l.d      $f4, 24($sp)
                lw       $fp, 28($sp)
                addi     $sp, $sp, 28
                jr       $ra
.data
xinput:.asciiz“\n请输入x\n”
epsilon输入:.asciiz“\n请输入epsilon\n”
sinxoutput:.asciiz“\n(x)是:”
.文本
主要:洛杉矶$a0,新普特
李$v0,4
系统调用
李$v0,7
系统调用
动产d$f2,$f12
la$a0,EPS输入
李$v0,4
系统调用
李$v0,7
系统调用
动产d$f0,$f12
日航浮标
洛杉矶$a0,辛克斯输出
李$v0,4
系统调用
李$v0,3
系统调用
李$v0,10
系统调用
floatsin:addi$sp,$sp,-64#帧
西南$ra,64($ra)
sw$fp,60$sp
s、 d$f0,56($sp)
s、 d$f4,48($sp)
s、 d$20,40($sp)
s、 d$f8,32($sp)
s、 d$f10,24($sp)
s、 d$f14,16($sp)
s、 d$f18,8($sp)
addi$fp$sp,64
li.d$f8,0.0#初始化
利达14美元,1.0美元
移动d$f16,$f0
里亚得$f18,0.0
日航环路p1
主循环:add.d$f18、$f18、$f4
c、 lt.d$f2,$f4
bc1f出口_fsin
日航环路p1
sub.d$f18、$f18、$f4
c、 lt.d$f2,$f4
bc1f出口_fsin
日航环路p1
j主回路
循环p1:add.d$f8,$f8,$f14
li.d$f10,1.0(j<2i-1)
动产d$f4$f16
li.d$f20,0.0
添加.d$f20、$f8、$f8
sub.d$f20,$f20,$f14
适用范围:c.lt.d$f10,$f20
bc1f环路p2
多个d$f4,$f4,$f16#(x*x)
加上d$f10,$f10,$f14
j代表
循环2:mov.d$f0,$f20
移动$t0,$ra
日本航空公司
d类$f4、$f4、$f12
jr$t0
退出fsin:mov.d$f12,$f18#写入目标寄存器
l、 d$f18,8($sp)#重写值
l、 d$f14,16($sp)
l、 d$f10,24($sp)
l、 d$f8,32($sp)
l、 d$20,40($sp)
l、 d$f4,48($sp)
l、 d$f0,56($sp)
lw$fp,60$sp
lw$ra,64$sp
附加$sp,$sp,64
jr$ra#返回给来电者
floatfac:addi$sp,$sp,-28#帧
sw$fp,28$sp
s、 d$f4,24($sp)
s、 d$f2,16($sp)
s、 d$f0,8($sp)
addi$fp$sp,28
li.d$f4,0.0
c、 le.d$f0,$f4
bc1t负片
利达12美元,1.0美元
li.d$f2,1.0
while:c.le.d$f0,$f2#中断条件
bc1t退出\u浮动事实
多个d$f12,$f12,$f0
sub.d$f0、$f0、$f2
j同时
负数:里亚得12美元,0.0
退出浮动事实:l.d$f0,8($sp)#重写值
l、 d$f2,16($sp)
l、 d$f4,24($sp)
lw$fp,28$sp
附加$sp,$sp,28
jr$ra

这是不正确的:
sw$ra,64$ra)

这里发生的事情是,您将
$ra
(0x40005c)的当前值存储在
64($ra)
,即
(0x40009c)
,从而覆盖指令
s.d$f14,16($sp)


您应该做的是
sw$ra,64($sp)

clang可以很好地组装您的代码
clang-target mips mips float.S-c
生成一个
.o
,该
llvm objdump-d
可以反汇编。我没有安装SPIM,也没有在火星上尝试过。你是说它会汇编,但在运行时会出错吗?是否可能在运行时使用错误的指针用数据重写代码?或者堆栈一直增长到与代码重叠?此时使用调试器检查
$sp
,并在错误发生后反汇编内存中的代码。是的,这是一个运行时错误,Michael在下面指出了问题。但你的评论有助于一般理解。