Код (Text): //----Цифра в строку------------------- void BinToStr(DWORD Digit,PBYTE pOut, int dSize) { int i = 0; BYTE High = 0, Low = 0; PBYTE pDigit= (PBYTE) &Digit; for(int j=0; dSize; dSize--, j++) { High = pDigit[j]; High >>= 0x4; Low = pDigit[j] &= 0x4; if(High >= 0xA) High += 0x31; else High += 0x30; if(Low >= 0xA) Low += 0x31; else Low += 0x30; pOut[i++] = High; pOut[i++] = Low; }//dSize pOut[i] = 0x0; } Суть в том что я передаю цифру в DWORD но сама цифра имеет размер в байтах dSize, хотелось бы сделать код, который был бы более наглядным, а по возможности и бытрее чем тот что выше
Нагляднее всего через табличку, ИМХО. Что-то вроде: Код (Text): static char hextbl[] = "0123456789ABCDEF"; void bin2hex(long x, char* s, int sz) { sz *= 2; while(sz--) *s++ = hextbl[x >> sz*4 & 0x0F]; *s = 0; } Насчет быстрее - надо подумать...
Вот что водится в дебрях моего винта: Код (Text): dw2hex:;(eax - num, edi - str) bswap eax mov ebx,0f0f0f0fh and ebx,eax xor eax,ebx shr eax,4 lea ecx,[eax+76767676h] lea edx,[ebx+76767676h] and ecx,90909090h and edx,90909090h shr ecx,4 shr edx,4 lea eax,[eax+ecx+2F2F2F2Fh] lea ebx,[ebx+edx+2F2F2F2Fh] xchg bl,ah rol eax,16 rol ebx,16 xchg bl,ah rol ebx,16 xchg ax,bx rol eax,16 stosd xchg eax,ebx stosd ret Только нужно зависимости поустранять.
Если я верно понял исходную задачу: Код (Text): void BinToStr(DWORD Digit, PBYTE pOut, int dSize) { int i = 0; BYTE High = 0, Low = 0; PBYTE pDigit= (PBYTE) &Digit; for(int j=0; dSize; dSize--, j++) { High = pDigit[j]; High >>= 0x4; // Low = pDigit[j] &= 0x4; Low = pDigit[j] &= 0xF; // if (High >= 0xA) High += 0x31; else High += 0x30; if ( High >= 0xA ) High += 'A'-10; else High += 0x30; // if (Low >= 0xA) Low += 0x31; else Low += 0x30; if ( Low >= 0xA ) Low += 'A'-10; else Low += 0x30; pOut[i++] = High; pOut[i++] = Low; }//dSize pOut[i] = 0x0; } То можно вот так: Код (Text): void BinToStr_NEW(DWORD Digit, PBYTE pOut, int dSize) { int tmpSize= dSize<<1; DWORD tmpDigit= ((Digit>>4)&0x0F0F0F0F)|((Digit<<4)&0xF0F0F0F0); PBYTE tmpOut= pOut; while ( tmpSize-- ) { BYTE tmp; tmp= (tmpDigit&0xF); *tmpOut++= tmp + '0' + (tmp/10)*('A'-10-'0'); tmpDigit>>= 4; } *tmpOut= 0x0; } PS Сорри, пост Black_mirror сразу не увидел.
Код (Text): 00000010: 8B43B0 mov eax,[ebx][-50] видим: 1. в байте байтое смещение (dSize равно 1) 2. B0 имеет старший бит в единице! Т.е. еще надо поставить перед числом на вывод и знак "-", т.е. ф-ция должна принимать еще один параметр, ставить знак или нет! зы: СПасибо Black_mirror за нюанс по поводу п.2 Но задача все же уместить в одной ф-ции, и по наглядней! Щас сам попробую реализовать, интересно как у меня получится
Убрал зависимости и добавил комментарии: Код (Text): dw2hex:;(eax - num, edi - str) mov ebx,eax ;87654321 rol eax,4 ;76543218 rol ebx,8 ;65432187 and eax,$0F0F0F0F ; 6 4 2 8 and ebx,$0F0F0F0F ; 5 3 1 7 lea ecx,[eax+76767676h] ;0-9 -> 76-7F lea edx,[ebx+76767676h] ;A-F -> 80-85 and ecx,90909090h ;0-9 -> 10 and edx,90909090h ;A-F -> 80 shr ecx,4 ;0-9 -> 01 shr edx,4 ;A-F -> 08 lea eax,[eax+ecx+2F2F2F2Fh];0-9 -> 30-39 lea ebx,[ebx+edx+2F2F2F2Fh];A-F -> 41-46 ror ax,8 ; 6 4 8 2 ror bx,8 ; 5 3 7 1 ror eax,8 ; 2 6 4 8 mov ecx,$FF00FF00 mov edx,$00FF00FF and ecx,eax ; 2 4 and edx,ebx ; 3 1 xor eax,ecx ; 6 8 xor ebx,edx ; 5 7 or edx,ecx ; 2 3 4 1 or eax,ebx ; 5 6 7 8 ror edx,8 ; 1 2 3 4 mov [edi],eax mov [edi+4],edx add edi,8 ret Минимальное время выполнения на атлоне 16 тактов (время выполнения чётвёртой итерации цикла из 8 вызовов данной функции - 128 тактов, в первых двух итерациях результат не стабильный, в третьей на 3 такта больше). Кто сможет побить этот рекорд? PS: предыдущий вариант выполнялся за 24 такта.
Замерял таким не хитрым кодом: Код (Text): sub esp,64 mov esi,4 .l0: mov edi,esp rdtsc push eax mov eax,1D34EF90h call dw2hex mov eax,1AE5C690h call dw2hex mov eax,2FFF456Ah call dw2hex mov eax,1DDFB495h call dw2hex mov eax,1F34EF92h call dw2hex mov eax,$D3453BC0 call dw2hex mov eax,$E2E5F450 call dw2hex mov eax,$A45AA45D call dw2hex rdtsc pop edx sub eax,edx dec esi jnz .l0 на выходе получал eax=80h
Black_mirror класс хорошо стыкуется с моей библиотечкой вывода строк - принял на вооружение. только ebx пришлось сохранить в esi - он у меня свободный.
Black_mirror Код (Text): dw2hex:;(eax - num, edi - str) movzx edx, ax ;00004321 shr eax, 12 ;00087654 shl edx, 4 ;00043210 shr ax, 4 ;00080765 shr dx, 4 ;00040321 shl eax, 8 ;08076500 shl edx, 8 ;04032100 shr ax, 4 ;08070650 shr dx, 4 ;04030210 shr al, 4 ;08070605 shr dl, 4 ;04030201 bswap eax ;05060708 bswap edx ;01020304 ;<спёр у Black_mirror> lea ecx, [eax+76767676h] ;0-9 -> 76-7F lea ebx, [edx+76767676h] ;A-F -> 80-85 and ecx, 90909090h ;0-9 -> 10 and ebx, 90909090h ;A-F -> 80 shr ecx, 4 ;0-9 -> 01 shr ebx, 4 ;A-F -> 08 lea eax, [eax+ecx+2F2F2F2Fh] ;0-9 -> 30-39 lea edx, [edx+ebx+2F2F2F2Fh] ;A-F -> 41-46 ;</спёр> mov [edi], eax mov [edi+4], edx add edi,8 ret Про athlon не знаю -- нет под рукой, на p4 твой код -- 58, мой -- 54