Assembly QtSpim汇编程序:使用双精度
我正在为课堂写一个程序。它从控制台获取x和epsilon,并应检索sin(x)近似值。当我在QtSpim中运行它时,我得到错误: 未知的指令类型:0 错误发生在以下位置: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)
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在下面指出了问题。但你的评论有助于一般理解。