1. 程式人生 > >[MIPS]匯編:利用int32實現int128(加法)

[MIPS]匯編:利用int32實現int128(加法)

進位 cti lse col 定義 code 32位 判斷 .com

問題描述:考慮到利用字符串實現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

[MIPS]匯編:利用int32實現int128(加法)