รหัสเครื่อง x86, 46 ไบต์
hexdump:
57 53 33 c0 33 ff f6 01 0f 75 15 6a 0a 5b 99 f7
f3 6b ff 0a 03 fa 33 c0 38 01 75 0f 97 5b 5f c3
69 c0 26 2b aa 6e 32 01 c1 e8 02 41 eb d8
มันเป็นfastcall
ฟังก์ชั่น - รับตัวชี้ไปยังสตริงในecx
และส่งคืนผลลัพธ์eax
และผลตอบแทนใน
ฟังก์ชั่นการแปลงแป้นพิมพ์จะคูณด้วยจำนวนเวทย์มนตร์1856645926
ทำ a XOR
ด้วยไบต์อินพุตและเลื่อนไปทางขวา 2 บิต
การบันทึกและกู้คืนการลงทะเบียน noclobber ( edi
และebx
) ใช้เวลา 4 ไบต์ แต่ฉันไม่พบวิธีที่มีประสิทธิภาพมากขึ้นในการดำเนินการนี้ การจัดเก็บค่าคงที่ 10 ในebx
นั้นน่ารำคาญเป็นพิเศษ!
ถอดชิ้นส่วนที่มีรหัสไบต์ที่สอดคล้องกัน:
57 push edi ; edi = result
53 push ebx ; we use ebx to store the constant 10
33 C0 xor eax,eax
33 FF xor edi,edi
myloop:
F6 01 0F test byte ptr [ecx],0Fh ; check for end of word
75 15 jne myhash
6A 0A push 0Ah
5B pop ebx
99 cdq ; prepare 64-bit dividend in edx:eax
F7 F3 div eax,ebx ; find the remainder of division by 10
6B FF 0A imul edi,edi,0Ah
03 FA add edi,edx ; update the result
33 C0 xor eax,eax ; reset the hash temporary variable
38 01 cmp byte ptr [ecx],al ; check for end of input (here al=0)
75 0F jne mycontinue
97 xchg eax,edi ; set the return register
5B pop ebx ; restore registers
5F pop edi ; restore registers
C3 ret
myhash:
69 C0 26 2B AA 6E imul eax,eax,6EAA2B26h ; hashing...
32 01 xor al,byte ptr [ecx] ; hashing...
C1 E8 02 shr eax,2 ; hashing...
mycontinue:
41 inc ecx ; next input byte
EB D8 jmp myloop
รหัส C ที่เทียบเท่ากัน:
int doit(const char* s)
{
int result = 0;
unsigned temp = 0;
while (true)
{
int c = *s++;
if ((c & 15) == 0)
{
temp %= 10;
result = result * 10 + temp;
temp = 0;
if (c == 0)
break;
else
continue;
}
temp *= 1856645926;
temp ^= c;
temp >>= 2;
}
return result;
}