Arrays 汇编Mips-转换两个字符串(包含Float)并找到它们之间的间隙
我必须创建一个函数,返回两个浮点数之间的差值 示例:用户A的lat为22.00,用户B的lat为20.00(或24.00)。结果必须为2.00 这是一个简单的减法耶。。。。。。我找到了一种不使用点和\n存储浮点的方法,但找不到在算术运算中使用数组的方法。这很令人沮丧 我希望有人能帮助我Arrays 汇编Mips-转换两个字符串(包含Float)并找到它们之间的间隙,arrays,assembly,floating-point,int,mips,Arrays,Assembly,Floating Point,Int,Mips,我必须创建一个函数,返回两个浮点数之间的差值 示例:用户A的lat为22.00,用户B的lat为20.00(或24.00)。结果必须为2.00 这是一个简单的减法耶。。。。。。我找到了一种不使用点和\n存储浮点的方法,但找不到在算术运算中使用数组的方法。这很令人沮丧 我希望有人能帮助我 .data dot: .asciiz "." aCapo: .asciiz "\n" A: .word nome1, cognome1, lat1, long1 nome1: .asciiz "Paol
.data
dot: .asciiz "."
aCapo: .asciiz "\n"
A: .word nome1, cognome1, lat1, long1
nome1: .asciiz "Paolo\n"
cognome1: .asciiz "Bonomi\n"
lat1: .asciiz "69.31\n"
long1: .asciiz "45.00\n"
B: .word nome2, cognome2, lat2, long2
nome2: .asciiz "Xhoni\n"
cognome2: .asciiz "Lara\n"
lat2: .asciiz "40.02\n"
long2: .asciiz "90.00\n"
array: .space 256
.text
.globl main
main:
la $a1, A
la $a2, B
la $t8, array
lw $s1, 8($a1)
lb $t0, 0($s1)
sb $t0, 0($t8)
lb $t0, 1($s1)
sb $t0, 1($t8)
lb $t0, 3($s1)
sb $t0, 2($t8)
lb $t0, 4($s1)
sb $t0, 3($t8)
编辑:我只是想办法做到这一点
这个功能很好用,顺便说一句,我知道它根本不起作用。。有这么多多余的工作,但我没有那么多时间,所以。。非常感谢你的提示和帮助
不同地理位置:
array: .word 1
array2: .word 1
risultatoLat: .word 1
empty: .word 1
risultatoLong: .word 1
empty2: .word 1
#
# this fuction takes two utentiR in $a1 and $a2
# and return the difference by lat and long from the two user
#
try_lat:
lw $s1, 8($a1) # put in s1 adress lat1
la $t8, array
lb $t0, 4($s1) #
sb $t0, 0($t8) #
lb $t0, 3($s1) #
sb $t0, 1($t8) #
lb $t0, 1($s1) #
sb $t0, 2($t8) #
lb $t0, 0($s1) #
sb $t0, 3($t8) #
lw $s0, 0($t8) # put in s0 lat1 without "." and "\n"
lw $s2, 8($a2) # put in s2 address lat2
la $t9, array2 #
lb $t0, 4($s2) #
sb $t0, 0($t9) #
lb $t0, 3($s2) #
sb $t0, 1($t9) #
lb $t0, 1($s2) #
sb $t0, 2($t9) #
lb $t0, 0($s2) #
sb $t0, 3($t9) #
lw $s1, 0($t9) # put in s1 lat2 without "." and "\n"
blt $s0, $s1, switch_utenti # if latA < latB goto switch
beq $s0, $s1, return_equal # if latA = latB return "00.00"
j do_sub_lat # else do sub
return_equal:
la $a0, str_diffLat # stamp "Differenza Latitudine: "
li $v0, 4
syscall
la $a0, str_same # stamp "00.00\n"
li $v0, 4
syscall
j try_long # goto process long
switch_utenti:
move $a0, $a1
move $a1, $a2
move $a2, $a0
do_sub_lat:
lw $s1, 8($a1) # put in s1 adress lat1
lw $s2, 8($a2) # put in s2 adress lat2
lb $t0, 0($s1) # load first number of lat1
lb $t1, 0($s2) # load first number of lat2
sub $t2, $t0, $t1 # t2 = t0 - t1 (decimal)
lb $t0, 1($s1) # load second number lat1
lb $t1, 1($s2) # load second number lat2
bge $t0, $t1, jEDLat # if (T0 >= T1) jump exception
li $t7, 1 # load 1 in t7
li $t6, 9 # load 9 in t6
sub $t2, $t2, $t7 # sub 1 from first number of the result
add $t0, $t0, $t6 # add 9 to t0
sub $t1, $t1, $t7 # sub 1 to t1 (i have to made this because if i try to ad 10 to t0, 10 will be like "a" no "10")
jEDLat:
sub $t3, $t0, $t1 # T0 - T1 risultato DECIMALE in T3
lb $t0, 3($s1) # carico secondo numero di A
lb $t1, 3($s2) # carico secondo numero di B
bge $t0, $t1, jETLat # if (T0 >= T1) salta eccezione
li $t7, 1 # carico 1 in T7
li $t6, 9 # carico 10 in T6
sub $t3, $t3, $t7
add $t0, $t0, $t6
sub $t1, $t1, $t7
jETLat:
sub $t4, $t0, $t1 # T0 - T1 risultato DECIMALE in T4
lb $t0, 4($s1) # carico quarto numero di A
lb $t1, 4($s2) # carico quarto numero di B
bge $t0, $t1, jEQLat # if (T0 >= T1) salta eccezione
li $t7, 1 # carico 1 in T7
li $t6, 9 # carico 10 in T6
sub $t4, $t2, $t7
add $t0, $t0, $t6
sub $t1, $t1, $t7
jEQLat:
sub $t5, $t0, $t1 # T0 -T1 risultato DECIMALE in T5
addi $t2, $t2, 48
addi $t3, $t3, 48
addi $t4, $t4, 48
addi $t5, $t5, 48
la $t8, risultatoLat
la $t7, aCapo
lb $t7, 0($t7)
sb $t7, 5($t8)
sb $t5, 4($t8)
sb $t4, 3($t8)
la $t7, dot
lb $t7, 0($t7)
sb $t7, 2($t8)
sb $t3, 1($t8)
sb $t2, 0($t8)
la $a0, str_diffLat
li $v0, 4
syscall
la $a0, risultatoLat
li $v0, 4
syscall
try_long:
lw $s1, 12($a1) # Metto in S1 la parola puntata da A1
la $t8, array
lb $t0, 4($s1) #
sb $t0, 0($t8) #
lb $t0, 3($s1) #
sb $t0, 1($t8) #
lb $t0, 1($s1) #
sb $t0, 2($t8) #
lb $t0, 0($s1) #
sb $t0, 3($t8) #
lw $s0, 0($t8) # IN S0 LONGITUDINE A
lw $s2, 12($a2) # Metto in S2 la parola puntata da A2
la $t9, array2
lb $t0, 4($s2) #
sb $t0, 0($t9) #
lb $t0, 3($s2) #
sb $t0, 1($t9) #
lb $t0, 1($s2) #
sb $t0, 2($t9) #
lb $t0, 0($s2) #
sb $t0, 3($t9) #
lw $s1, 0($t9) # IN S1 LONGITUDINE B
blt $s0, $s1, switch_utenti2 # se latA < latB inverto
beq $s0, $s1, return_equal2 # se latA = a latB ritorno 00.00
j do_sub_long
return_equal2:
la $a0, str_diffLong # stampo "Differenza Longitudine: "
li $v0, 4
syscall
la $a0, str_same # stampo "00.00\n"
li $v0, 4
syscall
jr $ra # fine funzione
switch_utenti2:
move $a0, $a1
move $a1, $a2
move $a2, $a0
do_sub_long:
lw $s1, 12($a1) # Metto in S1 la parola puntata da A1
lw $s2, 12($a2) # Metto in S2 la parola puntata da A2
lb $t0, 0($s1) # carico primo numero di A
lb $t1, 0($s2) # carico primo numero di B
sub $t2, $t0, $t1 # T0 - T2 risultato DECIMALE in T2
lb $t0, 1($s1) # carico secondo numero di A
lb $t1, 1($s2) # carico secondo numero di B
bge $t0, $t1, jEDLong # if (T0 >= T1) salta eccezione
li $t7, 1 # carico 1 in T7
li $t6, 9 # carico 10 in T6
sub $t2, $t2, $t7
add $t0, $t0, $t6
sub $t1, $t1, $t7
jEDLong:
sub $t3, $t0, $t1 # T0 - T1 risultato DECIMALE in T3
lb $t0, 3($s1) # carico secondo numero di A
lb $t1, 3($s2) # carico secondo numero di B
bge $t0, $t1, jETLong # if (T0 >= T1) salta eccezione
li $t7, 1 # carico 1 in T7
li $t6, 9 # carico 10 in T6
sub $t3, $t3, $t7
add $t0, $t0, $t6
sub $t1, $t1, $t7
jETLong:
sub $t4, $t0, $t1 # T0 - T1 risultato DECIMALE in T4
lb $t0, 4($s1) # carico quarto numero di A
lb $t1, 4($s2) # carico quarto numero di B
bge $t0, $t1, jEQLong # if (T0 >= T1) salta eccezione
li $t7, 1 # carico 1 in T7
li $t6, 9 # carico 10 in T6
sub $t4, $t2, $t7
add $t0, $t0, $t6
sub $t1, $t1, $t7
jEQLong:
sub $t5, $t0, $t1 # T0 -T1 risultato DECIMALE in T5
addi $t2, $t2, 48
addi $t3, $t3, 48
addi $t4, $t4, 48
addi $t5, $t5, 48
la $t7, aCapo
lb $t7, 0($t7)
la $t8, risultatoLong
sb $t7, 5($t8)
sb $t5, 4($t8)
sb $t4, 3($t8)
la $t7, dot
lb $t7, 0($t7)
sb $t7, 2($t8)
sb $t3, 1($t8)
sb $t2, 0($t8)
la $a0, str_diffLong
li $v0, 4
syscall
la $a0, risultatoLong
li $v0, 4
syscall
la $a0, aCapo
li $v0, 4
syscall
jr $ra
这太没用了我知道。。。如果我存储lat和long值,比如float,而不是ascii,可能会避免很多麻烦。我不确定你的意思: 找不到在算术运算中使用数组的方法 就像在汇编中一样,甚至没有一个定义良好的东西,比如“数组”,但您可能指的是一些连续的字节 像
sub
这样的算术指令只能在寄存器上工作(并且只能在字大小上工作)
因此,如果字符串中有两个ASCII“数字”,并且删除了小数点和换行符,如:
num1: .byte '1', '2', '7', '8', 0 # was "12.78\n"
num2: .byte '5', '6', '3', '4', 0 # was "56.34\n"
res: .space 16 # should be plenty for lat/lon difference
获取两个n1i=3,n2i=3的最后一位的索引,并设置resi=max(n1i,n2i)
现在,当您想要sub的绝对值时,您可以检查哪个数字较小,然后从较大的数字中减去那个数字
num1bigger = (n2i < n1i) || (n1i == n2i && first_different_digit_is_bigger_in_n1);
// equal numbers will produce "false"
这是每字节ASCII绝对值减法算法。(输入[22,20]和[22,24]都将产生+02结果!)
顺便说一句,对于非绝对减法,它实际上几乎是一样的,但是当时!num1biger
,负号必须在result=>22-24=-02
之前加上(现在前导的零看起来很糟糕:)
对于我的示例数组,循环中的值如下所示:
init:
num1bigger = false, borrow = false, res[4] = 0
Loop first iteration:
*1 fetching, swapping, borrow adjust: r1 = '4', r2 = '8'
*2 subtraction, adjustment: r3 = '6', borrow = true
*3 store result: res[3] = '6', n1i == n2i == resi == 2
(0 <= resi (2)) -> loop again
*1 fetching, swapping, borrow adjust: r1 = '3', r2 = '8'
*2 subtraction, adjustment: r3 = '5', borrow = true
*3 store result: res[2] = '5', n1i == n2i == resi == 1
(0 <= resi (1)) -> loop again
*1 fetching, swapping, borrow adjust: r1 = '6', r2 = '3'
*2 subtraction, adjustment: r3 = '3', borrow = false
*3 store result: res[1] = '3', n1i == n2i == resi == 0
(0 <= resi (0)) -> loop again
*1 fetching, swapping, borrow adjust: r1 = '5', r2 = '1'
*2 subtraction, adjustment: r3 = '4', borrow = false
*3 store result: res[0] = '4', n1i == n2i == resi == -1
!(0 <= resi (-1)) -> exit loop
// here res bytes are set to '4', '3', '5', '6', 0
// which can be formatted as result 43.56 (== 56.34 - 12.78)
init:
num1biger=false,借用=false,res[4]=0
循环第一次迭代:
*1取数、交换、借用调整:r1='4',r2='8'
*2减法,调整:r3='6',借用=真
*3存储结果:res[3]=“6”,n1i==n2i==resi==2
(0)再次循环
*1取数、交换、借用调整:r1='3',r2='8'
*2减法,调整:r3='5',借用=真
*3存储结果:res[2]=“5”,n1i==n2i==resi==1
(0)再次循环
*1取数、交换、借用调整:r1='6',r2='3'
*2减法,调整:r3='3',借用=假
*3存储结果:res[1]=“3”,n1i==n2i==resi==0
(0)再次循环
*1取数、交换、借用调整:r1='5',r2='1'
*2减法,调整:r3='4',借用=假
*3存储结果:res[0]=“4”,n1i==n2i==resi==1
!(0退出循环)
//此处res字节设置为“4”、“3”、“5”、“6”和“0”
//可将其格式化为结果43.56(=56.34-12.78)
…我不打算尝试在MIPS汇编中编写它,因为我从来没有在其中编写过代码,而且我也不能从您那里窃取所有的乐趣。我希望上面的内容能让您了解如何对ASCIIZ数字字符串进行算术运算
基本上,你们应该把它写在纸上,当你们每一步只能操作一位数的时候,你们会做什么,然后把它作为一个算法写下来
在几个值上尝试它(确保有一些特殊情况,比如我的“第一个不同的数字比第一个大”,或者两个相等的值,或者123.45-7.89
,0.00
输入,甚至可能是空字符串)
如果它看起来很可靠,只需在这些步骤之间编写指令(我试图将我的算法分解为许多简单的小步骤,其中大多数步骤最多只能由1-2条指令来解决,有时可能是3-4条指令,因为我太错过了MIPS体系结构。我习惯了x86指令,所以我尝试遵循更多类似RISC的逻辑(例如,避免使用标志),但仍然…).祝你好运,找到一个真正愿意花时间为你写这篇文章的人。你要求的是汇编语言!我已经记不太清楚这门语言了,否则我会尝试。你必须将lat和long值存储为ascii吗?如果你能将它们存储为浮点,这会容易得多。@Tim如果他没有字符串来浮点转换如果他知道小数点后总是只有2位,那么他可以使用100*整数来表示所有内容,只需在最后两位之前加上“”。
”。(我有点不知道,我从写ASCII—浮点转换器开始,可能是用C++来做的,那是一个背信弃义的代码).@Tim对于固定格式来说,它是..可能很简单..但在/10和/100之前,您已经引入了舍入,我不确定累积最小可能错误的正确策略。但是完整的浮点字符串解析,包括科学记数法和正确处理溢出/下溢…我不会写是的,但我认为它很容易消耗掉几天的时间来消除bug,而且感觉非常乏味。另外,我没有理由写它,我很乐意使用clib版本。:@Ped7g和Tim:Fast and precisionstrod()
是一个很难解决的问题,有很多特殊情况。详细描述了glibc使用的算法。它还有一个链接,指向另一个广泛使用的实现的类似描述(由David Gay编写):。有趣的阅读。这应该很容易扩展以处理点。
字符(它应该同时在num1/num2
中遇到,只需复制到res
,跳过减法并继续循环)。可能比从输入中删除它更容易。'\n'
也是如此,您可能可以将它们保留在那里,只要在加载\n
时跳转到下一个循环迭代即可。如果需要,甚至可以将其复制到结果中。
init:
already set: n1i, n2i, num1bigger, num1, num2, res, resi
borrow = false, res[resi+1] = 0
sub_loop:
*1 r1 = (0 <= n1i) ? num1[n1i--] : '0'
r2 = (0 <= n2i) ? num1[n2i--] : '0'
if (!num1bigger) swap(r1,r2)
// r1 is byte-part of bigger number, r2 of smaller
if (borrow) ++r2
*2 r3 = r1 - r2 // ASCII - ASCII = numeric value
borrow = (r3 < 0)
if (borrow) r3 += 10 // adjust negative into 0-9
r3 += '0' // add ASCII encoding back
*3 res[resi--] = r3
if (0 <= resi) jump sub_loop
// as the smaller number is subtracted from larger, borrow=0 at end
// so no need to patch the result in sign flip way
// but you may want to remove leading zeroes
// (but keep at least three of them for "0.00" result)
init:
num1bigger = false, borrow = false, res[4] = 0
Loop first iteration:
*1 fetching, swapping, borrow adjust: r1 = '4', r2 = '8'
*2 subtraction, adjustment: r3 = '6', borrow = true
*3 store result: res[3] = '6', n1i == n2i == resi == 2
(0 <= resi (2)) -> loop again
*1 fetching, swapping, borrow adjust: r1 = '3', r2 = '8'
*2 subtraction, adjustment: r3 = '5', borrow = true
*3 store result: res[2] = '5', n1i == n2i == resi == 1
(0 <= resi (1)) -> loop again
*1 fetching, swapping, borrow adjust: r1 = '6', r2 = '3'
*2 subtraction, adjustment: r3 = '3', borrow = false
*3 store result: res[1] = '3', n1i == n2i == resi == 0
(0 <= resi (0)) -> loop again
*1 fetching, swapping, borrow adjust: r1 = '5', r2 = '1'
*2 subtraction, adjustment: r3 = '4', borrow = false
*3 store result: res[0] = '4', n1i == n2i == resi == -1
!(0 <= resi (-1)) -> exit loop
// here res bytes are set to '4', '3', '5', '6', 0
// which can be formatted as result 43.56 (== 56.34 - 12.78)