Assembly 在MIPS的两个32b寄存器中存储由字符串表示的64位数字的算法
这是一个汇编语言问题。 我已经了解了如何将用户输入作为字符串接受并将其转换为整数 将当前和乘以10(向左移位3和移位1,然后将两个结果相加),然后从字符串中添加新数字(已通过减去48转换为数字)Assembly 在MIPS的两个32b寄存器中存储由字符串表示的64位数字的算法,assembly,64-bit,mips,32-bit,Assembly,64 Bit,Mips,32 Bit,这是一个汇编语言问题。 我已经了解了如何将用户输入作为字符串接受并将其转换为整数 将当前和乘以10(向左移位3和移位1,然后将两个结果相加),然后从字符串中添加新数字(已通过减去48转换为数字) 现在,直到溢出点,这将正常工作,但如何将数字分割成两个寄存器?它必须被除法还是移位?请详细解释 数字是位移位的。 您可以参考wiki上给出的乘法序列,了解LO和HI寄存器是如何填充的 LO = (($s * $t) << 32) >> 32; HI = ($s * $t) >
现在,直到溢出点,这将正常工作,但如何将数字分割成两个寄存器?它必须被除法还是移位?请详细解释 数字是位移位的。 您可以参考wiki上给出的乘法序列,了解LO和HI寄存器是如何填充的
LO = (($s * $t) << 32) >> 32;
HI = ($s * $t) >> 32;
LO=($s*$t)>32;
HI=($s*$t)>>32;
为此,您需要合成双宽度操作,即移位和加法 对于移位,除了分别移位两个半部外,还需要将溢出的顶部位从低半部移到高半部。为此,需要将低半部适当右移,然后使用按位
或
或加法将其移到高半部
在伪代码中(使用逻辑移位):
result_low=(原始低(32-n))
对于加法,您需要处理下半部分,然后检查它是否小于原始操作数之一。如果小于,则意味着发生溢出,您必须将进位与加数的上半部分和上半部分相加
result_low = op1_low + op2_low
result_high = op1_high + op2_high + ((result_low < op1_low) ? 1 : 0)
result\u low=op1\u low+op2\u low
结果高=op1高+op2高+((结果低
可能的asm实现:
la $t2, buff ; pointer to string
li $t0, 0 ; low
li $t1, 0 ; high
loop:
lb $t3, ($t2) ; load next byte
beq $t3, $zero, done ; end of string?
addi $t3, $t3, -48 ; convert from ascii
; t4,5 = t0,1 << 1
srl $t6, $t0, 31 ; t6 is used for the spilled bit
sll $t4, $t0, 1 ; shift low half
sll $t5, $t1, 1 ; shift high half
or $t5, $t5, $t6 ; put in the spilled bit
; t0,1 <<= 3
srl $t6, $t0, 29 ; the 3 spilled bits
sll $t0, $t0, 3 ; shift low half
sll $t1, $t1, 3 ; shift high half
or $t1, $t1, $t6 ; put in the spilled bits
; t0,1 += t4,5
addu $t0, $t0, $t4 ; add low halves
addu $t1, $t1, $t5 ; add high halves
sltu $t6, $t0, $t4 ; t6 = (t0 < t4), that is the carry
addu $t1, $t1, $t6 ; add the carry if any
; ok t0,1 has been multiplied by 10
addu $t0, $t0, $t3 ; just add the digit now
sltu $t6, $t0, $t3 ; the carry
addu $t1, $t1, $t6 ; add the carry if any
addiu $t2, $t2, 1 ; increment pointer
b loop ; and continue
done:
la$t2,buff;指向字符串的指针
李$t0,0;低
李$t1,0;高
循环:
lb$t3,($t2);加载下一个字节
beq$t3,$0,完成;字符串结束?
addi$t3、$t3、-48;从ascii转换
;t4,5=t0,1非常感谢,这非常有效。现在我将学习代码并遵循您的逻辑。这确实救了我
la $t2, buff ; pointer to string
li $t0, 0 ; low
li $t1, 0 ; high
loop:
lb $t3, ($t2) ; load next byte
beq $t3, $zero, done ; end of string?
addi $t3, $t3, -48 ; convert from ascii
; t4,5 = t0,1 << 1
srl $t6, $t0, 31 ; t6 is used for the spilled bit
sll $t4, $t0, 1 ; shift low half
sll $t5, $t1, 1 ; shift high half
or $t5, $t5, $t6 ; put in the spilled bit
; t0,1 <<= 3
srl $t6, $t0, 29 ; the 3 spilled bits
sll $t0, $t0, 3 ; shift low half
sll $t1, $t1, 3 ; shift high half
or $t1, $t1, $t6 ; put in the spilled bits
; t0,1 += t4,5
addu $t0, $t0, $t4 ; add low halves
addu $t1, $t1, $t5 ; add high halves
sltu $t6, $t0, $t4 ; t6 = (t0 < t4), that is the carry
addu $t1, $t1, $t6 ; add the carry if any
; ok t0,1 has been multiplied by 10
addu $t0, $t0, $t3 ; just add the digit now
sltu $t6, $t0, $t3 ; the carry
addu $t1, $t1, $t6 ; add the carry if any
addiu $t2, $t2, 1 ; increment pointer
b loop ; and continue
done: