Цифра в строку, как бы код по наглядней сделать?

Тема в разделе "WASM.ZEN", создана пользователем EvilsInterrupt, 26 сен 2006.

  1. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Код (Text):
    1. //----Цифра в строку-------------------
    2.  
    3. void
    4. BinToStr(DWORD Digit,PBYTE pOut, int dSize) {
    5.     int i = 0;
    6.     BYTE    High = 0, Low = 0;
    7.     PBYTE   pDigit= (PBYTE) &Digit;
    8.  
    9.     for(int j=0; dSize; dSize--, j++) {
    10.         High = pDigit[j]; High >>= 0x4;
    11.         Low = pDigit[j] &= 0x4;
    12.         if(High >= 0xA) High += 0x31;
    13.         else High += 0x30;
    14.         if(Low >= 0xA) Low += 0x31;
    15.         else Low += 0x30;
    16.         pOut[i++] = High;
    17.         pOut[i++] = Low;
    18.     }//dSize
    19.     pOut[i] = 0x0;
    20. }
    Суть в том что я передаю цифру в DWORD но сама цифра имеет размер в байтах dSize, хотелось бы сделать код, который был бы более наглядным, а по возможности и бытрее чем тот что выше
     
  2. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    сделай для байта, а для слова и двойного слова вызывай ту что для байта.
     
  3. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    shoo
    Слишком много махинаций и нет наглядности
     
  4. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Нагляднее всего через табличку, ИМХО.
    Что-то вроде:

    Код (Text):
    1. static char hextbl[] = "0123456789ABCDEF";
    2. void bin2hex(long x, char* s, int sz)
    3. {
    4.     sz *= 2;
    5.     while(sz--)
    6.         *s++ = hextbl[x >> sz*4 & 0x0F];
    7.     *s = 0;
    8. }
    Насчет быстрее - надо подумать...
     
  5. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Вот что водится в дебрях моего винта:
    Код (Text):
    1. dw2hex:;(eax - num, edi - str)
    2.         bswap eax      
    3.         mov ebx,0f0f0f0fh
    4.         and ebx,eax    
    5.         xor eax,ebx    
    6.         shr eax,4
    7.         lea ecx,[eax+76767676h]
    8.         lea edx,[ebx+76767676h]
    9.         and ecx,90909090h
    10.         and edx,90909090h
    11.         shr ecx,4
    12.         shr edx,4
    13.         lea eax,[eax+ecx+2F2F2F2Fh]
    14.         lea ebx,[ebx+edx+2F2F2F2Fh]
    15.         xchg bl,ah
    16.         rol eax,16
    17.         rol ebx,16
    18.         xchg bl,ah
    19.         rol ebx,16
    20.         xchg ax,bx
    21.         rol eax,16
    22.         stosd
    23.         xchg eax,ebx
    24.         stosd
    25.         ret
    Только нужно зависимости поустранять.
     
  6. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Если я верно понял исходную задачу:

    Код (Text):
    1. void BinToStr(DWORD Digit, PBYTE pOut, int dSize) {
    2.     int i = 0;
    3.     BYTE    High = 0, Low = 0;
    4.     PBYTE    pDigit= (PBYTE) &Digit;
    5.  
    6.     for(int j=0; dSize; dSize--, j++) {
    7.         High = pDigit[j]; High >>= 0x4;
    8.         // Low = pDigit[j] &= 0x4;
    9.         Low = pDigit[j] &= 0xF;
    10.         // if (High >= 0xA) High += 0x31; else High += 0x30;
    11.         if ( High >= 0xA ) High += 'A'-10; else High += 0x30;
    12.         // if (Low >= 0xA) Low += 0x31; else Low += 0x30;
    13.         if ( Low >= 0xA ) Low += 'A'-10; else Low += 0x30;
    14.         pOut[i++] = High;
    15.         pOut[i++] = Low;
    16.     }//dSize
    17.     pOut[i] = 0x0;
    18. }
    То можно вот так:

    Код (Text):
    1. void BinToStr_NEW(DWORD Digit, PBYTE pOut, int dSize)
    2. {
    3.     int tmpSize= dSize<<1;
    4.     DWORD tmpDigit= ((Digit>>4)&0x0F0F0F0F)|((Digit<<4)&0xF0F0F0F0);
    5.     PBYTE tmpOut= pOut;
    6.  
    7.     while ( tmpSize-- )
    8.     {
    9.         BYTE tmp;
    10.  
    11.         tmp= (tmpDigit&0xF);
    12.         *tmpOut++= tmp + '0' + (tmp/10)*('A'-10-'0');
    13.         tmpDigit>>= 4;
    14.     }
    15.     *tmpOut= 0x0;
    16. }
    PS Сорри, пост Black_mirror сразу не увидел.
     
  7. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
  8. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Код (Text):
    1. 00000010: 8B43B0                       mov         eax,[ebx][-50]
    видим:
    1. в байте байтое смещение (dSize равно 1)
    2. B0 имеет старший бит в единице! Т.е. еще надо поставить перед числом на вывод и знак "-", т.е. ф-ция должна принимать еще один параметр, ставить знак или нет!

    зы:
    СПасибо Black_mirror за нюанс по поводу п.2 :)

    Но задача все же уместить в одной ф-ции, и по наглядней! Щас сам попробую реализовать, интересно как у меня получится
     
  9. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Убрал зависимости и добавил комментарии:
    Код (Text):
    1. dw2hex:;(eax - num, edi - str)
    2.         mov ebx,eax             ;87654321
    3.         rol eax,4               ;76543218
    4.         rol ebx,8               ;65432187
    5.         and eax,$0F0F0F0F       ; 6 4 2 8
    6.         and ebx,$0F0F0F0F       ; 5 3 1 7
    7.         lea ecx,[eax+76767676h] ;0-9 -> 76-7F
    8.         lea edx,[ebx+76767676h] ;A-F -> 80-85
    9.         and ecx,90909090h       ;0-9 -> 10
    10.         and edx,90909090h       ;A-F -> 80
    11.         shr ecx,4               ;0-9 -> 01
    12.         shr edx,4               ;A-F -> 08
    13.         lea eax,[eax+ecx+2F2F2F2Fh];0-9 -> 30-39
    14.         lea ebx,[ebx+edx+2F2F2F2Fh];A-F -> 41-46
    15.         ror ax,8                ; 6 4 8 2
    16.         ror bx,8                ; 5 3 7 1
    17.         ror eax,8               ; 2 6 4 8
    18.         mov ecx,$FF00FF00
    19.         mov edx,$00FF00FF
    20.         and ecx,eax             ; 2   4
    21.         and edx,ebx             ;   3   1
    22.         xor eax,ecx             ;   6   8
    23.         xor ebx,edx             ; 5   7
    24.         or edx,ecx              ; 2 3 4 1
    25.         or eax,ebx              ; 5 6 7 8
    26.         ror edx,8               ; 1 2 3 4
    27.         mov [edi],eax
    28.         mov [edi+4],edx
    29.         add edi,8
    30.         ret
    Минимальное время выполнения на атлоне 16 тактов (время выполнения чётвёртой итерации цикла из 8 вызовов данной функции - 128 тактов, в первых двух итерациях результат не стабильный, в третьей на 3 такта больше).
    Кто сможет побить этот рекорд?

    PS: предыдущий вариант выполнялся за 24 такта.
     
  10. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Black_mirror
    Чем замерял? А то у меня Аналист в бсод валит.
     
  11. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Замерял таким не хитрым кодом:
    Код (Text):
    1.         sub esp,64
    2.         mov esi,4
    3.     .l0:
    4.         mov edi,esp
    5.         rdtsc
    6.         push eax
    7.         mov eax,1D34EF90h
    8.         call dw2hex
    9.         mov eax,1AE5C690h
    10.         call dw2hex
    11.         mov eax,2FFF456Ah
    12.         call dw2hex
    13.         mov eax,1DDFB495h
    14.         call dw2hex
    15.         mov eax,1F34EF92h
    16.         call dw2hex    
    17.         mov eax,$D3453BC0
    18.         call dw2hex
    19.         mov eax,$E2E5F450
    20.         call dw2hex
    21.         mov eax,$A45AA45D
    22.         call dw2hex
    23.         rdtsc
    24.         pop edx
    25.         sub eax,edx
    26.         dec esi
    27.         jnz .l0
    на выходе получал eax=80h
     
  12. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    Black_mirror
    класс :) хорошо стыкуется с моей библиотечкой вывода строк - принял на вооружение. только ebx пришлось сохранить в esi - он у меня свободный.
     
  13. clone

    clone New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2006
    Сообщения:
    84
    Black_mirror
    Код (Text):
    1. dw2hex:;(eax - num, edi - str)
    2.        movzx  edx, ax                     ;00004321
    3.        shr    eax, 12                     ;00087654
    4.  
    5.        shl    edx, 4                      ;00043210
    6.        shr    ax, 4                       ;00080765
    7.        shr    dx, 4                       ;00040321
    8.        shl    eax, 8                      ;08076500
    9.        shl    edx, 8                      ;04032100
    10.        shr    ax, 4                       ;08070650
    11.        shr    dx, 4                       ;04030210
    12.        shr    al, 4                       ;08070605
    13.        shr    dl, 4                       ;04030201
    14.  
    15.        bswap  eax                         ;05060708
    16.        bswap  edx                         ;01020304
    17.  
    18.        ;<спёр у Black_mirror>
    19.        lea    ecx, [eax+76767676h]        ;0-9 -> 76-7F
    20.        lea    ebx, [edx+76767676h]        ;A-F -> 80-85
    21.        and    ecx, 90909090h              ;0-9 -> 10
    22.        and    ebx, 90909090h              ;A-F -> 80
    23.        shr    ecx, 4                      ;0-9 -> 01
    24.        shr    ebx, 4                      ;A-F -> 08
    25.        lea    eax, [eax+ecx+2F2F2F2Fh]    ;0-9 -> 30-39
    26.        lea    edx, [edx+ebx+2F2F2F2Fh]    ;A-F -> 41-46
    27.        ;</спёр>
    28.  
    29.        mov    [edi], eax
    30.        mov    [edi+4], edx
    31.  
    32.        add edi,8
    33.        ret
    Про athlon не знаю -- нет под рукой, на p4 твой код -- 58, мой -- 54