ASC -> FPU

Тема в разделе "WASM.A&O", создана пользователем shoo, 10 дек 2004.

  1. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    Привет всем!

    Я не забыл за библиотеку! Эта темка - мое видение оной!

    По делу - я вот решил FPU освоить, процедурка в m32lib мне не приглянулась - вот, поэкспериментировал: потестируйте, если кому не лень. Замечания приветствуются, "ух ты" и "фу" - нет ;)


    Код (Text):
    1.  
    2. .data
    3.         align 4
    4. int10   dd  10
    5.  
    6. ten_1   dt  1.0e0001,1.0e0002,1.0e0003,1.0e0004
    7.         dt  1.0e0005,1.0e0006,1.0e0007,1.0e0008
    8.         dt  1.0e0009,1.0e0010,1.0e0011,1.0e0012
    9.         dt  1.0e0013,1.0e0014,1.0e0015
    10.  
    11. ten_16  dt  1.0e0016,1.0e0032,1.0e0048,1.0e0064
    12.         dt  1.0e0080,1.0e0096,1.0e0112,1.0e0128
    13.         dt  1.0e0144,1.0e0160,1.0e0176,1.0e0192
    14.         dt  1.0e0208,1.0e0224,1.0e0240
    15.  
    16. ten_256 dt  1.0e0256,1.0e0512,1.0e0768,1.0e1024
    17.         dt  1.0e1280,1.0e1536,1.0e1792,1.0e2048
    18.         dt  1.0e2304,1.0e2560,1.0e2816,1.0e3072
    19.         dt  1.0e3328,1.0e3584,1.0e3840,1.0e4096
    20.         dt  1.0e4352,1.0e4608,1.0e4864
    21.  
    22. .code
    23. a2f proc uses esi edi snum:DWORD
    24.     local num:  DWORD
    25.     local exp:  DWORD
    26.     local sign: DWORD
    27. ;-----------------------------
    28. ; ver. 3.1
    29. ;-----------------------------
    30. ; вход:     snum  - указатель на текстовый буфер с числом
    31. ; выход:    еах   - указатель на первый нераспознанный символ,
    32. ;                   или 0, если ошибка
    33. ;           zf    - 0, если не ошибка
    34. ;           st(0) - введенное число (если не ошибка)
    35. ;           есх   - ?
    36. ;-----------------------------
    37. ; преобразует текстовую строку
    38. ; в формате [+|-]999[.[999]][Е[+|-]999] в вещественное число.
    39. ; число цифр мантиссы и порядка не проверяется, но переполнение
    40. ; результата проверяется.
    41. ; введенное число возвращается в st(0).
    42. ; при ошибке указатель стека FPU восстанавливается.
    43. ; вызывающая процедура может проверить нераспознанный символ
    44. ; на допустимый разделитель.
    45. ;-----------------------------
    46. ;----------------------------- загрузка исходных значений
    47.     mov esi,snum
    48.     xor eax,eax
    49.     mov ecx,eax
    50.     mov edi,eax
    51.     mov sign,eax
    52.     fldz               
    53. ;----------------------------- проверка на знак числа
    54.     lodsb
    55.     cmp al,"+"
    56.     je a2i_loop
    57.     cmp al,"-"
    58.     jne a2i_after_sign
    59.     inc sign
    60. ;----------------------------- ввод мантиссы в st(0)
    61. a2i_loop:
    62.     lodsb
    63. a2i_after_sign:
    64.     cmp al,"."
    65.     je a2i_dot
    66.     cmp al,"0"
    67.     jc a2i_ex
    68.     cmp al,"9"+1
    69.     jnc a2i_ex
    70.     sub al,"0"
    71.     mov num,eax
    72.     fimul int10
    73.     fiadd num
    74.     inc edi
    75.     jmp a2i_loop
    76. a2i_dot_good:
    77.     mov ecx,esi
    78.     jmp a2i_loop
    79. a2i_dot:
    80.     jecxz a2i_dot_good ;------ иначе -> вторая точка в строке
    81. a2i_err:
    82.     ffree st(0)
    83.     fincstp
    84.     xor eax,eax ; <- неявная установка ZF
    85.     ret
    86. a2i_ex:
    87. ;----------------------------- завершающий код ввода мантиссы
    88.     test edi,edi
    89.     jz a2i_err
    90.     jecxz @F
    91. ;----------------------------- преобразование позиции точки в порядок
    92.     sub ecx,esi
    93.     inc ecx
    94. @@:
    95.     mov exp,ecx
    96.     cmp sign,0
    97.     je @F
    98.     fchs
    99. @@:
    100. ;----------------------------- конец ввода мантиссы
    101.     cmp al,"E"
    102.     je a2f_e
    103.     cmp al,"e"
    104.     je a2f_e
    105. a2f_ex_good:
    106. ;----------------------------- применение порядка
    107.     mov eax,exp
    108.     test eax,eax
    109.     jz p10_ex_z
    110.     pushf
    111.     jns @F
    112.     neg eax
    113. ;---------------- подгонка на случай большого числа цифр после точки
    114. p10_exp_chk:
    115.     cmp eax,4932
    116.     jl @F
    117.     fld ten_256
    118.     fdiv
    119.     sub eax,256
    120.     jmp p10_exp_chk
    121. @@:
    122.     mov edi,eax
    123.     fld1
    124.     and eax,0Fh
    125.     jz @F
    126.     add eax,eax
    127.     fld ten_1[eax+eax*4-10]
    128.     fmul
    129. @@:
    130.     mov eax,edi
    131.     shr al,4
    132.     and eax,0Fh
    133.     jz @F
    134.     add eax,eax
    135.     fld ten_16[eax+eax*4-10]
    136.     fmul
    137. @@:
    138.     mov eax,edi
    139.     mov al,ah
    140.     and eax,01Fh
    141.     jz @F
    142.     add eax,eax
    143.     fld ten_256[eax+eax*4-10]
    144.     fmul
    145. @@:
    146.     popf
    147.     js p10_ex_d
    148.     fmul
    149.     jmp p10_ex_z
    150. p10_ex_d:
    151.     fdiv
    152.     fstsw word ptr num
    153.     test  word ptr num,19h
    154.     jnz a2i_err
    155. ;----------------------------- нормальный выход
    156. p10_ex_z:
    157.     mov eax,esi
    158.     dec eax ; <- неявный сброс ZF
    159.     ret
    160. ;----------------------------- ввод порядка
    161. a2f_e:
    162. ;----------------------------- подготовка регистров
    163.     push edx
    164.     xor edi,edi
    165.     xor ecx,ecx
    166.     mov sign,edi
    167. ;----------------------------- поехали
    168.     lodsb
    169. ;----------------------------- проверка на знак порядка
    170.     cmp al,"+"
    171.     je a2f_e_loop
    172.     cmp al,"-"
    173.     jne a2f_e_after_sign
    174.     inc sign
    175. ;----------------------------- ввод числа порядка
    176. a2f_e_loop:
    177.     lodsb
    178. a2f_e_after_sign:
    179.     sub al,"0"
    180.     jc a2f_e_ex
    181.     cmp al,10
    182.     jnc a2f_e_ex
    183.     xchg ecx,eax
    184.     mul int10
    185.     add eax,ecx
    186.     cmp eax,4932 ; не превышает ли значение порядка 4932 ?
    187.     jg a2f_e_fail
    188.     xchg ecx,eax
    189.     inc edi
    190.     jmp a2f_e_loop
    191. a2f_e_ex:
    192. ;----------------------------- введена ли хоть одна цифра?
    193.     pop edx
    194.     test edi,edi
    195.     jz a2i_err
    196.     cmp sign,0
    197.     je @F
    198.     neg ecx
    199. @@:
    200. ;----------------------------- коррекция порядка
    201.     add exp,ecx
    202.     jmp a2f_ex_good    
    203. ;----------------------------- порядок некорректен - откат
    204. a2f_e_fail:
    205.     pop edx
    206.     jmp a2i_err
    207.    
    208. a2f endp
    209.  




    пример вызова:
    Код (Text):
    1.    ...
    2.    push offset text_buffer_containing_number
    3.    call a2f
    4.    jz error_input_1 ; ошибка формата
    5.    mov al,byte ptr [eax]
    6.    test al,al
    7.    jnz error_input_2 ; неверный разделитель
    8.    ...
    9.  


    канэшна, credits: спасибо всем за все хорошее :)

    01>забыл за .data?

    02>значительно переделал (если кто ваще заметил ;)

    03> --//--

    04>не удержался - микроизменение - теперь число значащих цифр мантиссы просто не должно превышать 4931... и все.



    след. число прохавано:

    test_ db "13225468798796464654626576565768765464647"

    db "65472679872687626786826746872646846265455"

    db "32547265424564265465465465254642645646265"

    db "65276842684628746268426872687462464682468"

    db "."

    db "62874684246268435587387597624648942684862"

    db "E-000000000000000000000000000000000004777"

    db 0



    ; ST0 valid 1.3225468798796464650e-4614



    а винкалькулятор его не съел :)
     
  2. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    Все! надаела! дальше улучшать не хочу, разве если только явная ошибка будет - исправлю. кушает вроде все от 1е4932 до 1е-4932. проверял на прилепленной проге под олей. не пишите только 257 цифр после запятой с порядком -49хх - может не понять. (меньше - должна, по идее).

    [​IMG] 256403655__fpu_lab.zip