m32lib bug: dwtoa

Тема в разделе "WASM.ASSEMBLER", создана пользователем yureckor, 11 июл 2005.

  1. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    subj

    процедура dwtoa из библиотеки MASM32 (без нового SP, сейчас не знаю) by Tim Roberts/Alexander Yackubtchik слетает на некоторых числах. Пример: -1501748189 (0A67D2423h).
     
  2. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Она не слетает, просто неверный результат выдаёт. По причине отсутствия обработки знака.

    Пользуйся atol
     
  3. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    какого знака?

    она переваривает числа меньше 0 (со знаком), там в начале проверка стоит.



    Я на скорую руку написал такую:
    Код (Text):
    1.  
    2. pecreg10 proc chislo:DWORD, mem:DWORD
    3. pushad
    4.  mov edi, [mem]
    5.  mov eax, [chislo]
    6.  
    7.  mov PW [edi], "0"
    8.  test eax,eax
    9.  jz @@kon
    10.  jns @@pos
    11.  mov PW [edi],'-'
    12.  neg eax
    13.  inc edi
    14.  @@pos:      
    15.  
    16.  xor ecx, ecx
    17.  mov ebx, 10
    18.  @@1:
    19.   inc ecx
    20.   xor edx, edx
    21.   div ebx
    22.   push edx
    23.  CP eax, 0, NZ, @@1
    24.  
    25.  @@2:
    26.   pop eax
    27.   add eax, "0"
    28.   mov [edi], al
    29.   inc edi
    30.  dnz ecx, @@2
    31.  
    32. dec edi
    33. @@kon:
    34. inc edi
    35. mov [pecreg_kon], edi
    36. mov PB [edi], 0
    37. stc
    38. popad
    39. ret
    40. pecreg10 endp
    41.  
     
  4. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Как она его переваривает?


    Код (Text):
    1. num_string db '-1501748189',0    ;твоя строка
    2.  
    3. invoke atodw, addr num_string
    4. PrintDec eax                     ;[b]eax = 1766010845[/b]
    5. PrintHex eax                     ;[b]eax = 69432FDD[/b]
    6.  




    А говоришь знак переваривает :)

    Может она его в прямом смысле слова переваривает?
     
  5. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    тфу, sorry

    dwtoa



    PS: модераторы, подправьте название темы plz
     
  6. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Вот на медленную руку:




    Код (Text):
    1. r_divisor   dd  -858993459
    2.  
    3. cr_dwtostr proc dwDword:DWORD, lpOutString:DWORD
    4.     option  prologue : none
    5.     option  epilogue : none
    6.  
    7.     push    esi
    8.     push    edi
    9.     mov     edi,[esp+16]                ;lpOutString
    10.     mov     esi,[esp+12]                ;dwDword
    11.     cmp     esi,0
    12.     jg      _loop
    13.     jz      _zero
    14.     neg     esi
    15.     mov     byte ptr[edi],2Dh
    16.     inc     edi
    17.     inc     dword ptr[esp+16]           ;lpOutString
    18.  
    19. align 16    
    20. _loop:
    21.     mov     eax,esi
    22.     mul     r_divisor
    23.     shr     edx,3
    24.     mov     ecx,edx
    25.     lea     ecx,[ecx*4+ecx]
    26.     add     ecx,ecx
    27.     neg     ecx
    28.     add     ecx,esi
    29.     mov     byte ptr[edi],30h
    30.     or      [edi],cl
    31.     mov     esi,edx
    32.     test    edx,edx
    33.     lea     edi,[edi+1]
    34.     jnz     _loop
    35.    
    36.  @@:
    37.     mov     byte ptr[edi],0
    38.     mov     esi,[esp+16]
    39. align 16
    40.  @@:
    41.     dec     edi
    42.     mov     al,[esi]
    43.     mov     dl,[edi]
    44.     mov     [edi],al
    45.     mov     [esi],dl
    46.     inc     esi
    47.     cmp     esi,edi
    48.     jl      @B
    49.    
    50.     pop     edi
    51.     pop     esi
    52.     retn    8
    53.    
    54. _zero:
    55.     mov     word ptr[edi],30h
    56.     pop     edi
    57.     pop     esi
    58.     retn    8
    59.     option  prologue : prologuedef
    60.     option  epilogue : epiloguedef
    61. cr_dwtostr endp
     
  7. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    У меня нормально сконвертировало.

    Уже тучу лет назад этот баг был выловлен, исправленая версия послана куда только можно. Стив просто тупит каждый раз и не меняет версию.

    Вот тестовая программа

    Вот код нормальной atodw (от кода Тима там только ножки да рожки честно говоря) (PS для новых процов начало лучше бы другое)
    Код (Text):
    1.  
    2. ;##################################################################### ####  
    3.     ; -----------------------------------------
    4.     ; This procedure was written by Tim Roberts  and Svin
    5.     ; -----------------------------------------      
    6.       .386
    7.       .model flat, stdcall  ; 32 bit memory model
    8.       option casemap :none  ; case sensitive    
    9.      .code
    10.  
    11. ; ###################################################################### ###    
    12. OPTION PROLOGUE:NONE
    13. OPTION EPILOGUE:NONE
    14. atodw proc FORCENOFRAME
    15. ;uses edi esi String:PTR BYTE  
    16.  
    17.       ;----------------------------------------
    18.       ; Convert decimal string into dword value       ; return value in eax
    19.       ;----------------------------------------      
    20. ;String equ [esp+4]
    21.     push esi
    22.     mov esi,[esp+8]
    23.     sub ecx,ecx
    24.     cmp byte ptr [esi],2Eh ;"-"+1
    25.     sbb edx,edx
    26.     mov eax,ecx
    27.     adc esi,ecx
    28.     jmp @F
    29. again:  lea eax,[eax+4*eax]
    30.     inc esi
    31.     lea eax,[ecx+2*eax]
    32. @@: mov cl,[esi]
    33.     sub cl,30h
    34.     jns again
    35.     add eax,edx
    36.     pop esi
    37.     xor eax,edx
    38.     retn 4
    39.         atodw endp  
    40.  
    41. ; ###################################################################### ###  
    42.  
    43. end  
    44.  




    [​IMG] 2138736227__testdwta.rar
     
  8. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    The Svin

    Вы привели код atodw, а аттач хоть и называется dwtoa но вызывает atodw.



    Ошибочна процедура dwtoa (печати числа).

    Это которая
    Код (Text):
    1.  
    2. dwtoa proc dwValue:DWORD, lpBuffer:DWORD
    3. ; -------------------------------------------------------------
    4.     push ebx
    5.     push esi
    6.     push edi
    7.  
    8.     mov eax, dwValue
    9.     mov edi, [lpBuffer]
    10.  
    11.     or eax,eax
    12.     jnz sign
    13.    
    14.   zero:
    15.     mov word ptr [edi],30h
    16.     jmp dw2asc
    17.    
    18.   sign:
    19.     jns pos
    20.     mov byte ptr [edi],'-'
    21.     neg eax
    22.     inc edi
    23.  
    24.   pos:      
    25.     mov ecx,429496730
    26.     mov esi, edi
    27.  
    28.     .while (eax > 0)
    29.       mov ebx,eax
    30.       mul ecx
    31.       mov eax,edx
    32.       lea edx,[edx*4+edx]
    33.       add edx,edx
    34.       sub ebx,edx
    35.       add bl,'0'
    36.       mov [edi],bl
    37.       inc edi
    38.     .endw
    39.  
    40.     mov byte ptr [edi], 0       ; terminate the string
    41.  
    42.     ; We now have all the digits, but in reverse order.
    43.  
    44.     .while (esi < edi)
    45.       dec edi
    46.       mov al, [esi]
    47.       mov ah, [edi]
    48.       mov [edi], al
    49.       mov [esi], ah
    50.       inc esi
    51.     .endw
    52.  
    53.     dw2asc:
    54.  
    55.     pop edi
    56.     pop esi
    57.     pop ebx
    58.  
    59.     ret
    60.  
    61. dwtoa endp
    62.  
     
  9. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    yureckor



    Кстати, о птицах: попробовал dwtoa из masmlib - работает, ничего не вылетает, возвращает строку нормально.

    Может в чём другом проблема?
     
  10. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    yureckor

    Про это тоже известно, опять же проблемы со Стивом по замене на правильную написанную тучу лет назад:
    Код (Text):
    1.  
    2. OPTION PROLOGUE:NONE
    3. OPTION EPILOGUE:NONE
    4.  
    5. dwtoa proc arg1, arg2
    6. dwValue  equ [esp+16]
    7. lpBuffer equ [esp+20]
    8.       push esi
    9.       push edi
    10.       push ebx
    11.  
    12.       mov   eax, dwValue
    13.       mov edi,lpBuffer
    14.       test eax,eax  ;it'll set both sf and zf
    15.       jnz sign
    16. zero:     mov word ptr [edi],30h
    17.       pop ebx
    18.       pop edi
    19.       pop esi
    20.       retn 8
    21. sign:     jns pos       ;sf already set  by or eax,eax we don't need cmp it again
    22.       mov byte ptr [edi],'-'
    23.       neg eax
    24.       inc edi
    25. pos:     
    26.     mov ecx,429496730
    27.     mov byte ptr [edi][10],0
    28.     lea esi, [edi][9]
    29.     cmp eax,10
    30.     jl less10
    31.  
    32. @@: mov ebx,eax
    33.     mul ecx    
    34.     mov eax,edx ;edx == reminder of division eax by 10
    35.  
    36.     lea edx,[edx+edx*4]
    37.     add edx,edx
    38.     .IF edx > ebx ;check for exeption array
    39.     sub edx,10    ;correct result
    40.     dec eax
    41.     .ENDIF
    42.  
    43.     sub ebx,edx
    44.     add bl,30h
    45.     mov [esi],bl
    46.     dec esi
    47.     cmp eax,9   ;don't do last iteration if it's already figure
    48.     ja @B
    49.  
    50. less10:  
    51.     or al,30h       ;just convert it to simbol
    52.     mov edx,[esi+8] ;shift to the beginning of the buffer
    53.     mov [esi],al
    54.     mov ecx,[esi+4]
    55.     mov eax,[esi]
    56.     mov [edi][4],ecx
    57.     mov [edi],eax
    58.     mov [edi][8],edx
    59.     pop ebx
    60.     pop edi
    61.     pop esi
    62.    
    63.     retn 8
    64. dwtoa endp
    65. ; ###################################################################### ###
    66.  
    67.     end
    68.  
     
  11. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    yureckor













    Че это за 'ортодокс' ? ;)





    <sub>Почему самолет не на микрософт направили... :dntknw:</sub>
     
  12. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    imho,



    PB equ byte ptr

    PW equ word ptr



    Остальные — оригинально :)
     
  13. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    yureckor equ человек-макрос

    :)



    dnz ecx, @@2

    это видимо

    dec ecx

    jnz @@2



    CP eax, 0, NZ, @@1

    похоже на

    cmp eax,0

    jnz @@1
     
  14. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    dnz - это от Спековской привычки :)

    CP - чтоб короче было
    Код (Text):
    1.  
    2. ;-
    3. dnz MACRO QAX,M
    4.  dec QAX
    5.  jnz M
    6. ENDM
    7.  
    8. ;-
    9. CP MACRO QAX,QBX,J1,M
    10. IF ((@SizeStr(<QBX>) GT 1) AND (@InStr(1,<QBX>,<0>) EQ 1)) OR (@InStr(1,<QBX>,<FALSE>) EQ 1) OR (@InStr(1,<QBX>,<NULL>) EQ 1)
    11.  IF $x_reg(QAX) AND ( (@InStr(1,<QBX>,<Z>) EQ 1)OR(@InStr(1,<QBX>,<z>) EQ 1)OR(@InStr(1,<QBX>,<NZ>) EQ 1)OR(@InStr(1,<QBX>,<nz>) EQ 1) )
    12.         test QAX, QAX
    13.         J&J1 M
    14.  ELSE
    15.         cmp QAX,QBX
    16.         J&J1 M
    17.  ENDIF
    18. ELSE
    19.         cmp QAX,QBX
    20.         J&J1 M
    21. ENDIF
    22.  
    23. ENDM
    24.  
    25. ;-
    26. $x_reg MACRO x:REQ
    27. IF (OPATTR (x)) AND 00010000y
    28.  EXITM <-1> ;TRUE
    29. ELSE
    30.  EXITM <0> ;FALSE
    31. ENDIF
    32. ENDM
    33.  
    34.