[MIPS]汇编:利用int32实现int128(加法)

问题描述:考虑到利用字符串实现int128相比于利用4个int32实现int128消耗更多的内存,所以在对内存有需求的情况下可以利用4个int32,进行高低位运算,从而实现int128的加法和减法

                     将一个Int128位分成如图的四个int32的变量

在将a和b的对应位相加时,先取一个Int32的低十六位相加,判断是否要向高十六位进位,然后再对高十六位相加,最后通过按位与的操作完成一个Int32位的计算,重复该过程直到算完HIGHEST位的值即可

直接上汇编代码

#int128u
#author: moonlightcn
#time: 2019/05/13
#所有内置数据符合计算机内补码表示(十六进制)
#测试样例aa = 0xaaa11aaffff11ffffed111fffff   bb = 0x22ffffed222fffff
#tex和kex以及hi,lo是掩码,用来完成特定操作
#hi和lo用来完成取int32的高16位和低16位
#tex用来完成判读是否进位,kex得到计算后的值
.data
    hi: .word 0xffff0000
    lo: .word 0xffff
    tex: .word 0x10000
    kex: .word 0xffff
    aa: .word 0x111fffff,0x11ffffed,0x11abffff,0xaaa                        #aa和bb是测试样例,cc保存值,aa和bb,cc从左到右都是低位到高位
    bb: .word 0x222fffff,0x22ffffed,0,0
    cc: .word 0,0,0,0
    prompt: .asciiz "0x"
.text
    .ent main
    .globl main
main:
    la $a1,aa
    la $a2,bb
    la $a3,cc
    jal int128u_add
    jal print_int128
    li $v0,10
    syscall
####################################################################################
#int128u_add function:
#     int flag=0                      flag判读是否需要进位
#{   for(int i=1;i<=4;i++)
#    {     取aa和bb数组得第i个元素
#          int ta = aa(i) & lo ,tb =  bb(i)&lo
#          if(需要进位,也就是flag=1)
#             int t = ta + tb + 1
#             if(t & tex)            判读该十六位加完是否溢出
#                  flag = 1
#                  cc(i) = (t & kex)    取加完得值
#             else   flag = 0 , cc(i) = t
#          else(不需要进位,也就是flag=0)
#             int t = ta + tb
#             if(t & tex)
#                  flag = 1
#                  cc(i) = (t & kex)
#             else flag = 0 , cc(i) = t
#          从这里开始计算高位
#          ta = (aa(i) & hi) >> 16 , tb = (bb(i) & hi) >>16
#          if(需要进位)
#             int t = ta + tb + 1
#             cc(i) = cc(i) | ( t << 16 )
#             if(t & tex)  flag = 1
#             else  flag = 0
#          else (不需要进位) 
#             int t = ta + tb
#             cc(i) = cc(i) | ( t << 16 )
#             if(t & tex)  flag = 1
#             else flag = 0
#end function
###################################################################################
int128u_add:
     li $a0,0                           #a0 == flag ,a1 is a pointer to the array a, b is the pointer to the arry b
     li $t0,1                           #t0 == int i for loop
     j loop
done:
     jr $ra
loop:
     bgt $t0,4,done
     addi $t0,$t0,1                      #t1 === ta,  #t2 === tb
     lw $t1,0($a1)
     lw $t2,0($a2)
     lw $t4,lo
     and $t1,$t1,$t4
     and $t2,$t2,$t4
     beq $a0,1,loop1f                            #if (flag == 1)
     addu $t1,$t1,$t2
     lw $t4,tex
     and $t2,$t1,$t4
     bnez $t2,loop1e1
     li $a0,0
     sw $t1,0($a3)
     j loop2
loop1e1:
     li $a0,1
     lw $t4,kex
     and $t1,$t1,$t4
     sw $t1,0($a3)
     j loop2
loop1f:
     lw $t4,tex
     addu $t1,$t1,$t2
     addu $t1,$t1,1
     and $t2,$t1,$t4
     bnez $t2,loop1f1                            #if (t & tex)
     li $a0,0
     sw $t1,0($a3)
     j loop2
loop1f1:    
     li $a0,1
     lw $t4,kex
     and $t3,$t1,$t4
     sw $t3,0($a3)
     j loop2
loop2:
     lw $t4,hi
     lw $t1,0($a1)
     lw $t2,0($a2)
     lw $t3,0($a3)
     and $t1,$t1,$t4
     and $t2,$t2,$t4
     srl $t1,$t1,16
     srl $t2,$t2,16
     beq $a0,1,loop2f
     lw $t4,kex
     addu $t1,$t1,$t2
     and $t2,$t1,$t4
     sll $t2,$t2,16
     or $t3,$t3,$t2
     sw $t3,0($a3)
     lw $t4,tex
     and $t1 $t1,$t4
     bnez $t1,loop2e1
     li $a0,0
     addi $a1,$a1,4
     addi $a2,$a2,4
     addi $a3,$a3,4
     j loop
loop2e1:
     li $a0,1
     addi $a1,$a1,4
     addi $a2,$a2,4
     addi $a3,$a3,4
     j loop
loop2f:
     addu $t1,$t1,$t2
     addu $t1,$t1,1
     lw $t3,0($a3)
     lw $t4,kex
     and $t2,$t1,$t4
     sll $t2,$t2,16
     or $t3,$t3,$t2
     sw $t3,0($a3)
     lw $t4,tex
     and $t1,$t1,$t4
     bnez $t1,loop2f1
     li $a0,0
     addi $a1,$a1,4
     addi $a2,$a2,4
     addi $a3,$a3,4
     j loop
loop2f1:
     li $a0,1
     addi $a1,$a1,4
     addi $a2,$a2,4
     addi $a3,$a3,4
     j loop
#######################################################################################
#该函数要从cc的末尾开始,因为该程序定义cc(1)低位,cc(2)低位, cc(3)高位,cc(4)最高位
#print_int128 function (接受一个参数,在这里为cc数组得指针)
#{
#        cout << " 0x "
#        int t
#        for( int i = 1 ;i <= 4 ; i++)
#          for( int j = 28 ; j >= 0 ; j -= 4)
#               t = cc(i) >> j 
#               t &= 15
#               if ( t < 10 ) cout << t 
#               else{
#                         char k = ( t - 10 ) + 97
#                         cout << k
#               }
#}
#end function
########################################################################################
print_int128:
     la,$a3,cc
     addi $a3,$a3,12
     li $v0,4
     la $a0,prompt
     syscall
     li $t0,1
     j lop
lop:
     bgt $t0,4 done1
     addi $t0,$t0,1
     lw $t4,0($a3)
     addi $a3,$a3,-4
     li $t1,28
case1:
     bltz $t1,lop
     move $t3,$t4
     srlv $t3,$t3,$t1
     andi $t3,$t3,15
     blt $t3,10 lop1
     addi $t3,$t3,-10
     li $v0,11
     addi $a0,$t3,97
     syscall
     addi $t1,$t1,-4
     j case1
lop1:
     li $v0,1
     move $a0,$t3
     syscall
     addi $t1,$t1,-4
     j case1
done1:
    li $v0,11
    li $a0,10
    syscall
    jr $ra

猜你喜欢

转载自www.cnblogs.com/mlcn-2000/p/10878978.html