assembly 在MIPS汇编程序中比较浮点值与1

70gysomp  于 2022-11-30  发布在  其他
关注(0)|答案(1)|浏览(212)

用户输入浮点值,它们被保存在堆栈中,然后以相反的顺序打印出来。如果用户输入小于或等于1的值,它应该跳过该值。但这不起作用。为什么?

.data
strN: .asciiz "n=? \n"
strEingabe: .asciiz "te Zahl = ? \n"
strAusgabe: .asciiz "te Zahl = \n"
strNewLine: .asciiz "\n"
strNegative: .asciiz "\n Fehler: Ungültiger Wert für n!\n"
.text
.globl main

main:
li $v0, 4
la $a0, strN
syscall
li $v0, 5
syscall
move $s0, $v0           # $s0 = n
li $v0, 4
la $a0, strNewLine
syscall
bgtz $s0, input_loop_init
j negative

input_loop_init:
li $s1, 1
j input_loop

input_loop:
li $v0, 1
move $a0, $s1
syscall
li $v0, 4
la $a0, strEingabe
syscall
li $v0, 6       #read float, save in $f0
syscall 
mfc1 $t0, $f0
bgt $t0, 1, input_loop1
j input_loop

input_loop1:
addi $sp, $sp, -4
sw $t0, 0($sp)
li $v0, 4
la $a0, strNewLine
syscall
addiu $s1, $s1, 1
ble $s1, $s0, input_loop
j output_loop_init



output_loop_init:
move $s1, $s0
j output_loop

output_loop:
li $v0, 1
move $a0, $s1
syscall
li $v0, 4
la $a0, strAusgabe
syscall
lw $a0, 0($sp)
mtc1 $a0, $f12
addi $sp, $sp, 4
li $v0, 2
syscall
li $v0, 4
la $a0, strNewLine
syscall
addi $s1, $s1, -1
bgt $s1, $zero, output_loop
j exit

negative:
li $v0, 4
la $a0, strNegative
syscall
j exit

exit:
li $v0, 10
syscall

我试过使用cvt.s.w之类的东西,但我还不完全理解它的作用。无论我做了什么,它要么说“不正确类型的操作数”,要么只返回用户输入的所有内容,无论是什么值(除非他输入了小于0的东西!)

mgdq6dx1

mgdq6dx11#

处理器很少直接提供两种不同数据类型的算术(如比较)方法;通常算术运算采用相同类型的两个操作数-因此可以比较整数与整数或浮点与浮点,但不能比较浮点与整数(不能直接比较)。
因此,您需要决定是将浮点数转换为整数,然后作为整数进行比较,还是将1转换为浮点数,然后作为浮点数进行比较。
前者(将float转换为int,以便进行int-to-int比较)会有损失,因为转换为integer会丢失所有小数位。
而后者(将int转换为float以进行float-to-float比较)也可能会有问题,因为float计算并不总是产生相同的位模式-但是,与1比较(1.0)的情况下应该没问题。如果这样做可能会出现问题,例如,(1.0/3.0)*3.0 -它可能打印输出为1.0,但与另一个1.0的位模式不完全相同,因此不会比较是否相等!(浮点Maven知道要避免相等比较,并以不同的方式设计他们的算法。)
您还需要了解寄存器是如何工作的。寄存器保存位模式--将寄存器的值从内存传输到内存,或者从int型寄存器传输到float型寄存器,或者从float型寄存器传输到int型寄存器,都不会改变位模式。只有显式转换和算术运算会改变位模式。处理器假定所使用的指令与寄存器中给定的位模式相匹配。
因此,将float移到integer寄存器会原样复制位模式,而不会转换为integer(反之亦然,将int复制到float寄存器,数字还没有变成浮点格式)。
转换(例如int与float之间的cvt.s.w)完全在浮点寄存器组中进行。整数寄存器没有用于浮点格式的指令,只能按原样复制。
要使用整数寄存器将float转换为int以便与int进行比较,请首先在float寄存器中将float转换为int,然后复制到整数寄存器并使用normal(integer)beq & bne,例如.
要将1从int转换为float,请将1加载到integer寄存器,然后从integer寄存器复制到float寄存器,再在float寄存器中将其转换为float。最后进行float与float的比较,设置浮点条件代码,可以使用bc1fbc1t进行测试。
另一种方法是直接将一个常量float值放在内存中,如OneF: .float 1.0,这将避免运行时从int转换,当然,由于它在内存中,你必须将它从内存加载到一个float寄存器中(使用l.s(我的偏好)或lwc1,这是相同的)。
如果您选择尝试用double代替float,那么我建议您坚持使用偶数浮点寄存器编号,因为这样会稍微简化一些。

相关问题