相關資訊
本類常用軟件
-
福建農村信用社手機銀行客戶端下載下載量:584204
-
Windows優化大師下載量:416898
-
90美女秀(視頻聊天軟件)下載量:366961
-
廣西農村信用社手機銀行客戶端下載下載量:365699
-
快播手機版下載量:325855
眾所周知在Intel80x86指令集中有div這么一條指令,在32bit下,其功能是把edx,eax組成的64bit無符號整數(edx高32bit,eax低32bit)除以原32bit操作數,商放入eax中,余數放入edx中,但是在很多情況下我們的被除數只有32bit,除數是一個固定的值,此時如果還使用div指令,會使程序運行效率下降,我為此想到一種方法,可以比通常的div指令在時間上快很多,具體的實現原理很簡單,我們可以使用mul指令來代替div指令,要知道mul的執行所消耗的cpu周期大大低于div指令所消耗的,那如何做呢?
我們回想我們上小學的時候,老師們就講過除以一個數等于乘以這個數的倒數,對,就是這個簡單的法則!但一個問題又來了,一個大于1的整數的倒數小于1啊,是小數啊,而mul指令只能做無符號整數乘法啊.這的確是個問題,但我有很好的解決方法,我一切的思想都是從二進制出發的,但為此我們最多只能完成32bit除以32bit了.
現在我們假設235/10,對應的二進制表達就是11101011b/1010b,此時我們用mul來實現,我們先求出10的倒數1/10,1/10=0.000110011001100110011001100......b,是小數怎么辦呢?我們可以把她變成整數,為了得到更精確的結果,我們取精度最高的32bit整數110011001100...1101(0xCCCCCCCD),相當于左移了35位,這樣結果很明顯也左移的35位,我們發現本來左移35位后0位應該是0啊?怎么是1呢,這主要是從精度上考慮,我們可以忍受結構比實際的大這么一點點,因為可以使用and指令來屏蔽掉,得到正確的商,但如果結果小于了,那就沒辦法了.
說這么多我們來看看具體的程序,我采用把32bit無符號數轉換為10進制字符串輸出的函數為例子來說明這個方法的優越性.
這是通常的方法:
printfd proc UnInteger,lpBuff
xor edx,edx
mov ecx,10
mov edi,lpBuff
mov eax,UnInteger
add edi,10
mov byte ptr[edi],dl
@@:
div ecx
dec edi
or edx,30h
mov [edi],dl
xor edx,edx
test eax,eax
jnz @b
mov eax,edi;此時eax為轉換后的字符串首地址
ret
printfd endp
下面是改進的方法:
printfd proc UnInteger,lpBuff
mov esi,lpBuff
mov eax,UnInteger
add esi,10
mov ecx,0CCCCCCCDh
mov byte ptr[esi],0
@@:
mov ebx,eax
mul ecx
mov eax,edx
and edx,-8;屏蔽誤差
shr eax,3
sub ebx,eax
sub ebx,eax
sub ebx,edx
or ebx,30h
dec esi
mov [esi],bl
test eax,eax
jnz @b
mov eax,esi;此時eax為轉換后的字符串首地址
ret
printfd endp
經過我的測試,第二個的處理時間大約為第一個的1/3,當然是在處理同一個數的情況下.