Assembly 在MIPS的两个32b寄存器中存储由字符串表示的64位数字的算法

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) >

这是一个汇编语言问题。 我已经了解了如何将用户输入作为字符串接受并将其转换为整数

将当前和乘以10(向左移位3和移位1,然后将两个结果相加),然后从字符串中添加新数字(已通过减去48转换为数字)


现在,直到溢出点,这将正常工作,但如何将数字分割成两个寄存器?它必须被除法还是移位?请详细解释

数字是位移位的。 您可以参考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: