Assembly 将双倍存储在堆栈中并获取结果
我必须在汇编MIPS中执行以下操作。我要求用户给我一个数字,比如说N,然后用户给我N个值(单精度数字),我必须将这些值转换成双倍,然后计算总和。但是计算必须通过一个过程来完成,每次都得到2个双倍的参数并返回总和。因此,对于用户给我的每个值,我调用该过程,2个参数将是当前值和前一个(总和)。我对所有N个值都这样做。 总金额在寄存器$f2中。在jr$ra之后,我将$f0添加到先前的$f2值中,循环再次开始。 这是我的程序Assembly 将双倍存储在堆栈中并获取结果,assembly,stack,double,mips,Assembly,Stack,Double,Mips,我必须在汇编MIPS中执行以下操作。我要求用户给我一个数字,比如说N,然后用户给我N个值(单精度数字),我必须将这些值转换成双倍,然后计算总和。但是计算必须通过一个过程来完成,每次都得到2个双倍的参数并返回总和。因此,对于用户给我的每个值,我调用该过程,2个参数将是当前值和前一个(总和)。我对所有N个值都这样做。 总金额在寄存器$f2中。在jr$ra之后,我将$f0添加到先前的$f2值中,循环再次开始。 这是我的程序 addition: addi $sp, $sp, -16
addition:
addi $sp, $sp, -16
sdc1 $f2, 8($sp)
sdc1 $f4, 0($sp)
add.d $f0, $f2, $f4
ldc1 $f4, 0($sp)
ldc1 $f2, 8($sp)
addi $sp, $sp, 16
jr $ra
每次我进行示例时,都会收到消息:0x004000b0处的运行时异常:地址未在双字边界0x7fffefdc上对齐
如果这里看不到问题,我愿意发布更多的代码
我将非常感谢您的帮助即使乍一看您正确地使用了对齐偏移量,但如果
$sp
本身不是8字节对齐的,这对您没有多大好处。您可以确保它已对齐或使用未对齐的访问
请注意,sdc1
写入内存,ldc1
从内存加载。因此,我认为您的代码没有任何意义将$f2
和$f4
保存到堆栈中,并恢复它们,特别是因为它们没有被更改
还不清楚您尝试使用什么呼叫约定
更新:使用在$f12
和$f14
中传递双参数并在$f0
中返回的标准约定,代码可能如下所示:
.globl main
main:
li $v0, 5 # read_int
syscall
move $s0, $v0 # $s0 is the counter
sub.d $f20, $f20, $f20 # zero $f20, the sum
blez $s0, done
loop:
li $v0, 6 # read_float
syscall
cvt.d.s $f12, $f0 # convert read number to double, pass as first arg
mov.d $f14, $f20 # sum as second arg
jal addition # add them
mov.d $f20, $f0 # update sum
addiu $s0, $s0, -1 # decrement counter
bgtz $s0, loop # repeat
done:
mov.d $f12, $f20 # sum as argument
li $v0, 3 # print_double
syscall
li $v0, 10 # exit
syscall
addition:
add.d $f0, $f12, $f14 # result = arg1 + arg2
jr $ra
以下是我在每个循环结束时所做的:cvt.d.s$f6,$f4 jal add.d$f2,$f2,$f0 addi$t1,$t1,1J循环。我如何使$sp 8字节对齐?为什么我不需要保存和加载f寄存器呢?如果你在你的过程之后有了加法,那么你的过程就没有任何意义了。您应该只添加该过程。为什么您需要保存和加载寄存器,尤其是在它们保持不变的情况下?这是家庭作业项目的一部分。需要这样做。它说使用下面用C写的过程如下:二次加法(double a,double b){double result;result=a+b;return result;}是的,这与我说的没有冲突。它没有说任何地方可以保存/恢复f寄存器,或者在之后使用另一个加法器。也许我不明白你在说什么,杰斯特先生。你对我的问题有什么建议?