2016-06-07 82 views
-1

我正在尋找一種方法將64位數字轉換爲使用32位系統的字符串(也可能是其他方式)。我不是要求代碼,只是要求一些想法。如何將64位數轉換爲x86程序集中的字符串?

+1

這會給你的想法= http://stackoverflow.com/questions/30243848/assembly-x86-date-to-number-breaking-a-string-into-smaller-sections/30244131#30244131。它用於16位和32位,您將其修復爲64位。試一試,如果你有問題,發佈你的代碼,我們會幫助你。 –

+0

你的64位數字到底如何?如果它在'rax'或其他一些64位寄存器中,則無法使用純保護模式指令集訪問高32位。 – Olipro

+0

@JoseManuelAbarcaRodríguez我對這種裝配不熟悉。我在ubuntu上使用AT&T語法。我知道轉換其他大小的熱門,關於64位數字的問題是如何將其兩個32位部分(更高和更低)結合起來,從而得到原始的64位數字。 – sstefan

回答

3

唯一困難的部分是在32位機器上將64位數字除以10。其他一切與數字適合單個寄存器的正常情況幾乎相同。

通常你可以看看gcc的輸出如何做事ASM提示,但在這種情況下,它just calls the __udivdi3 libgcc helper function:/

如果你只是在做這個作爲一個學習鍛鍊的時候,那麼很可能你應該只查找一個擴展精度的div算法並使用它。 Here's one,書中使用英特爾語法和16位操作。變量名稱很清晰,並且有解釋性文本,所以您應該可以重新實現它的32位。谷歌在這個詞組中更多的點擊,和/或看看libgcc的源代碼。

又見implementing school-like division on 32bit chunks on x86


如果您正在實施這是真的(高性能):

記住86的div指令做了64B/32B - > 32B師(但如果故障商溢出一個32位寄存器)。所以你可以檢查你的高級雙字的低位是否足夠小,如果是這樣的話,第一步只需要一個單位來得到高位數字。

只要您的號碼小到可以用一個div進行分割,就可以跳出擴展精度循環,並且每個數字使用一個單獨的div

這可能只需要一次迭代就可以減少到32位數。在這一點上,你可以通過使用10乘法逆劃分:

// from the godbolt link: gcc5.3 -O3 -m32 
uint32_t div10_u32(uint32_t x) { return x/10; } 
    movl $-858993459, %edx  # 0xcccccccd 
    movl %edx, %eax   # gcc is dumb: no need for this mov. clang avoids it 
    mull 4(%esp) 
    movl %edx, %eax 
    shrl $3, %eax 
    ret 

說明如何使用的一個完整的乘法結果的高半部分(32bx32b-> 64B)。


這可能會更快使用乘法逆做整個事情,即使這意味着做一個64×64B - 在32位機器上> 128B乘法。整數除法非常緩慢,只是流水線,但integer mul is very fast on Intel CPUs

AVX512-DQ adds a 64x64 -> 64b low multiply instruction,但那不能延長精度。 AVX512-IFMA增加了52bx52b低位和高位乘法指令,因此在幾年之內,可能需要一個代碼路徑(在AVX512-IFMA硬件上運行的32位二進制代碼),當您的編號的前64-52位是全零。

相關問題