2011-11-23 63 views
2

我試圖將CrapWOW散列從http://www.team5150.com/~andrew/noncryptohashzoo/CrapWow.html轉換爲delphi或寧可basm。我的ASM技能非常有限,但我認爲它不會太難...彙編轉換爲basm

無論如何,在一些關於asm轉換的網頁的幫助下,我來到這個,但它不工作...尤其是,對於最後一部分我不知道如何轉換。這是寄存器賦值給參數和返回參數嗎?

function CrapWow(key: PAnsiChar; len, seed: Cardinal): Cardinal; 
//finline u32 fastcall CrapWow(const u8 *key, u32 len, u32 seed) { 
// #if !defined(__LP64__) && !defined(_MSC_VER) && (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)) 
// // esi = k, ebx = h 
// u32 hash; 
// asm(
asm 
    lea esi, 5052acdbh[ecx+esi] //leal 0x5052acdb(%ecx,%esi), %esi 
    mov ebx, ecx    //movl %ecx, %ebx 
    cmp ecx, 8     //cmpl $8, %ecx 
    jb @DW 

@QW:      //QW%=: 
    mov eax, 5052acdbh   //movl $0x5052acdb, %eax 
    mul [edi]     //mull (%edi)     << CRASH HERE 
    add ecx, -8     //addl $-8, %ecx 
    xor ebx, eax    //xorl %eax, %ebx 
    xor esi, edx    //xorl %edx, %esi 
    mov eax, 57559429h   //movl $0x57559429, %eax 
    mul 4[edi]     //mull 4(%edi) 
    xor esi, eax    //xorl %eax, %esi 
    xor ebx, edx    //xorl %edx, %ebx 
    add edi, 8     //addl $8, %edi 
    cmp ecx, 8     //cmpl $8, %ecx 
    jae @QW      //jae QW%= 

@DW:      //DW%=: 
    cmp ecx, 4     //cmpl $4, %ecx 
    jb @B      //jb B%= 
    mov eax, 5052acdbh   //movl $0x5052acdb, %eax 
    mul [edi]     //mull (%edi) 
    add edi, 4     //addl $4, %edi 
    xor ebx, eax    //xorl %eax, %ebx 
    add ecx, -4     //addl $-4, %ecx 
    xor esi, edx    //xorl %edx, %esi 

@B:       //B%=: 
    test ecx, ecx    //testl %ecx, %ecx 
    jz @F      //jz F%= 
    shl ecx, 3     //shll $3, %ecx 
    mov edx, 1     //movl $1, %edx 
    mov eax, 57559429h   //movl $0x57559429, %eax 
    shl edx, cl     //shll %cl, %edx 
    add edx, -1     //addl $-1, %edx 
    and edx, [edi]    //andl (%edi), %edx 
    mul edx      //mull %edx 
    xor esi, eax    //xorl %eax, %esi 
    xor ebx, edx    //xorl %edx, %ebx 

@F:       //F%=: 
    lea edx, 5052acdbh[esi]  //leal 0x5052acdb(%esi), %edx 
    xor edx, ebx    //xorl %ebx, %edx 
    mov eax, 5052acdbh   //movl $0x5052acdb, %eax 
    mul edx      //mull %edx 
    xor eax, ebx    //xorl %ebx, %eax 
    xor esi, edx    //xorl %edx, %esi 
    xor eax, esi    //xorl %esi, %eax 

//No idea how to convert this... 
// : =a(hash), =c(len), =S(len), =D(key) 
// : c(len), S(seed), D(key) 
// : %ebx, %edx, cc 
// ); 
// return hash;} 
end; 

我很樂意在這方面得到一些幫助。

knight_killer

+0

而且我不確定這個哈希是如此快速的設計。它對每個DWORD使用一個乘法運算,所以它可能比優化的per-8 crc32有預先計算好的表格或一個很好的普通K&R慢。這個哈希算法只是乘法哈希函數+移位的另一種變體。內部沒有新的想法。提供的asm代碼遠沒有優化(沒有好的流水線工作)。我比較喜歡http://www.strchr.com/hash_functions頁面來比較速度 - 這是獨立的。恕我直言,主要瓶頸將是內存或硬盤驅動器訪問,而不是使用自己的算法。 –

+5

調用約定與[Delphi's](http://docwiki.embarcadero.com/RADStudio/en/Using_Inline_Assembly_Code)不符。所需的寄存器不會被保留(ebx + esi + edi)。首先將其轉換爲Delphi代碼(使用'cardinal'作爲您的值)。所以你也會有一個x64的準備版本。然後看看生成的asm - 如果只有PUREPASCAL版本很慢,請優化Delphi生成的asm。不要太早優化。此外,我懷疑代碼不可重入(而crc32或adler32可以調用一次或每個塊)。 –

+0

@Arnaud,我的目的是比較你的SynZip中的CrapWOW和CRC32,以及BASM新聞組中一個優化的MurMur2,以及我自己的基準(特定的密鑰大小,平均表大小等)。我沒有想到asm與basm有所不同,因此將C代碼轉換爲delphi可能更好。 –

回答

1

看起來EDI在被初始化之前使用。它似乎稍後會與其他寄存器一起發生。您應該在輸入過程代碼時檢查原始代碼編譯器如何設置這些寄存器,並檢查您是否正確複製了它們。看起來也在你的問題的意見。

0

是的。它看起來EDI是在被初始化之前使用的,因爲你正在使用「mul [edi]」指令,所以你用指針傳遞了len參數。