Значение длинного текстового числа

Тема в разделе "WASM.BEGINNERS", создана пользователем assch, 22 мар 2024.

  1. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Как в 32-битной системе взять значения длинного текстового числа

    Если предпологаемое выходное значение не превышает 4-байта
    то сделать это очень просто

    Код (ASM):
    1.  
    2. .data
    3. text db '1234567890'
    4. .code
    5.  
    6. lea ecx,text
    7. xor eax,eax
    8. xor edx,edx
    9. Loc__1:
    10. mov dl,byte ptr [ecx]
    11. if dl
    12. sub dl,'0'
    13. imul eax,10
    14. add eax,edx
    15. inc ecx
    16. jmp Loc__1
    17. endif
    18.  
    На выходе в регистре - eax
    будет полноценное значение - 1234567890

    Но если текстовое число предпологает 8-байтное значение
    например к предыдущему примеру мы в текстовое число добавим в конце единицу

    то по сути должно получится 8-байтное значение - 02DFDC1C35h (hex-формат)
    но если мы пропустим это текстовое число через этот же алгоритм

    Код (ASM):
    1.  
    2. .data
    3. text db '12345678901'
    4. .code
    5.  
    6. lea ecx,text
    7. xor eax,eax
    8. xor edx,edx
    9. Loc__1:
    10. mov dl,byte ptr [ecx]
    11. if dl
    12. sub dl,'0'
    13. imul eax,10
    14. add eax,edx
    15. inc ecx
    16. jmp Loc__1
    17. endif
    18.  
    То на выходе в регистре - eax
    будет значение только младшего (dword) 8-байтного значения - 0DFDC1C35h

    А как сделать так чтобы узнать
    значение старшего (dword) 8-байтного значения - 02h

    Кто в теме подскажите пожалуйста
     
  2. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    что сие значит?
    оно просто строка
    значит и работайте с байтами строки
     
  3. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    94
    Так у вас же есть команды для умножения. Просто сделайте умножение в столбик чисел с двумя 32-разрядными цифрами
    Код (ASM):
    1. .data
    2.   text          db '1234567890123456789', 0
    3. .code
    4.         push    ebx
    5.         push    esi
    6.         push    edi
    7.         lea     ebx, [text]
    8.         xor     ecx, ecx
    9.         xor     esi, esi
    10.         mov     edi, 10
    11.  
    12.   next:
    13.         cmp     byte [ebx], 0 ; Конец строки
    14.         jz      quit
    15.         xchg    eax, esi ; Умножаем старшую 32-разрядную цифру на основание ссч текстового числа
    16.         mul     edi
    17.         xchg    eax, ecx ; Умножаем младшую 32-разрядную цифру на основание ссч текстового числа
    18.         mul     edi
    19.         add     edx, ecx ; Учитываем перенос
    20.         jc      overflow ; Число больше 64 разрядов
    21.         movzx   ecx, byte [ebx]
    22.         xor     esi, esi
    23.         sub     ecx, '0'
    24.         cmp     ecx, edi ; Цифра числа верная (меньше основания ссч)?
    25.         jae     error
    26.         add     ecx, eax ; Складываем умноженное число с новой цифрой из строки
    27.         adc     esi, edx
    28.         jnc     next
    29.  
    30.   overflow: ; Ошибка в длине числа (превосходит 64 бита)
    31.         push    MB_OK or MB_ICONERROR
    32.         push    error_head
    33.         push    error_text
    34.         push    0
    35.         call    MessageBoxW
    36.         xor     ecx, ecx
    37.         xor     esi, esi
    38.         jmp     quit
    39.  
    40.   error: ; Ошибка в записи числа
    41.         push    MB_OK or MB_ICONERROR
    42.         push    error_head
    43.         push    error_text2
    44.         push    0
    45.         call    MessageBoxW
    46.         xor     ecx, ecx
    47.         xor     esi, esi
    48.  
    49.   quit:
    50.         mov     eax, ecx
    51.         mov     edx, esi
    52.         pop     edi
    53.         pop     esi
    54.         pop     ebx
    55.         retn
    56.  
    57.   error_head    db 'Str2Int', 0
    58.   error_text    db 'Value out of range!', 0
    59.   error_text2   db 'Invalid number!', 0
    60.  
     
    Последнее редактирование: 22 мар 2024
  4. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Спасибо за участие
     
  5. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    По итогу проанализировав полученные данные за которые огромное спасибо
    в том числе и данные полученные на дружественных сайтах
    я сформировал четыре пользовательские функции
    которые в принцыпи можно рассматривать просто как алгоритм действий

    Стоит обратить внимание на то что в функциях нет выявления ошибок
    и подразумевается что текстовое число имеет только десятичные символы
    с обязательным финализирующим нулём

    Каждая функция имеет только один параметр это адрес текстового числа

    Синтаксис функций не обычный но я думаю будет интуитивно понятным

    Если предполагаемое значение текстовых чисел 4-байта

    Код (ASM):
    1.  
    2. func Fun1Dword esi,p[1]
    3. ;---------------------------------------------------------------------
    4. mov esi,p1
    5. xor eax,eax
    6. xor edx,edx
    7. Loc__1:
    8. mov dl,[esi]
    9. if dl
    10. sub dl,'0'
    11. imul eax,10
    12. add eax,edx
    13. inc esi
    14. jmp Loc__1
    15. endif
    16. ;---------------------------------------------------------------------
    17. ; на выходе:
    18. ; eax - 4-байтное значение
    19. ;---------------------------------------------------------------------
    20. end
    21.  
    Если предполагаемое значение текстовых чисел 8-байт

    Код (ASM):
    1.  
    2. func Fun2Dword esi edi ebx,p[1]
    3. ;---------------------------------------------------------------------
    4. mov esi,p1
    5. xor eax,eax ; младшие 4 байта (биты 0-3)
    6. xor edx,edx ; старшие 4 байта (биты 4-7)
    7. xor ecx,ecx
    8. Loc__1:
    9. mov cl,[esi]
    10. inc esi
    11. if cl
    12. sub cl,'0'
    13. add eax,eax ; *2
    14. adc edx,edx
    15. mov edi,eax
    16. mov ebx,edx
    17. add eax,eax ; *4
    18. adc edx,edx
    19. add eax,eax ; *8
    20. adc edx,edx
    21. add eax,edi
    22. adc edx,ebx
    23. add eax,ecx
    24. jmp Loc__1
    25. endif
    26. ;---------------------------------------------------------------------
    27. ; на выходе:
    28. ; eax - младший dword 8-байтного значения
    29. ; edx - старший dword 8-байтного значения
    30. ;---------------------------------------------------------------------
    31. end
    32.  
    Если предполагаемое значение текстовых чисел 12-байт
    Код (ASM):
    1.  
    2. func Fun3Dword esi edi ebx,p[1]
    3. ;---------------------------------------------------------------------
    4. local tmp1,tmp2
    5. ;---------------------------------------------------------------------
    6. mov esi,p1
    7. xor eax,eax ; младшие 4 байта (биты 0-3)
    8. xor edx,edx ; (биты 4-7)
    9. xor ebx,ebx ; старшие 4 байта (биты 8-11)
    10. xor ecx,ecx
    11. Loc__1:
    12. mov cl,[esi]
    13. if cl
    14. sub cl,'0'
    15. add eax,eax ; *2
    16. adc edx,edx
    17. adc ebx,ebx
    18. mov edi,eax
    19. mov [tmp1],edx
    20. mov [tmp2],ebx
    21. add eax,eax ; *4
    22. adc edx,edx
    23. adc ebx,ebx
    24. add eax,eax ; *8
    25. adc edx,edx
    26. adc ebx,ebx
    27. add eax,edi
    28. adc edx,[tmp1]
    29. adc ebx,[tmp2]
    30. add eax,ecx
    31. adc edx,0
    32. adc ebx,0
    33. inc esi
    34. jmp Loc__1
    35. endif
    36. ;---------------------------------------------------------------------
    37. ; на выходе:
    38. ; eax - младший dword 12-байтного значения
    39. ; edx - следующий dword 12-байтного значения
    40. ; ebx - старший dword 12-байтного значения
    41. ;---------------------------------------------------------------------
    42. end
    43.  
    Если предполагаемое значение текстовых чисел 16-байт

    Код (ASM):
    1.  
    2. func Fun4Dword esi edi ebx,p[1]
    3. ;---------------------------------------------------------------------
    4. local tmp1,tmp2,tmp3,tmp4
    5. ;---------------------------------------------------------------------
    6. mov esi,p1
    7. xor eax,eax ; младшие 4 байта (биты 0-3)
    8. xor edx,edx ; (биты 4-7)
    9. xor ebx,ebx ; (биты 8-11)
    10. xor edi,edi ; старшие 4 байта (биты 12-15)
    11. xor ecx,ecx
    12. Loc__1:
    13. mov cl,[esi]
    14. if cl
    15. sub cl,'0'
    16. add eax,eax ; *2
    17. adc edx,edx
    18. adc ebx,ebx
    19. adc edi,edi
    20. mov [tmp1],eax
    21. mov [tmp2],edx
    22. mov [tmp3],ebx
    23. mov [tmp4],edi
    24. add eax,eax ; *4
    25. adc edx,edx
    26. adc ebx,ebx
    27. adc edi,edi
    28. add eax,eax ; *8
    29. adc edx,edx
    30. adc ebx,ebx
    31. adc edi,edi
    32. add eax,[tmp1]
    33. adc edx,[tmp2]
    34. adc ebx,[tmp3]
    35. adc edi,[tmp4]
    36. add eax,ecx
    37. adc edx,0
    38. adc ebx,0
    39. inc esi
    40. jmp Loc__1
    41. endif
    42. ;---------------------------------------------------------------------
    43. ; на выходе:
    44. ; eax - младший dword 16-байтного значения
    45. ; edx - следующий dword 16-байтного значения
    46. ; ebx - следующий dword 16-байтного значения
    47. ; edi - старший dword 16-байтного значения
    48. ;---------------------------------------------------------------------
    49. end
    50.  
    По сути то что я хотел я узнал

    Ещё раз всем спасибо за участие в теме

    Век живи век учись
     
  6. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    Как насчет более длинных чисел?
    128-256-512 бит?
     
  7. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    128 бит показан в четвёртой функции
    а 256 и 512 бит тоже можно сделать
    просто для этого нужно больше задействовать переменных и освободить какой нибудь регистр
    для перекидывания данных

    но это чистой воды экзотика
    --- Сообщение объединено, 23 мар 2024 ---
    Прошу прощения в четвёртой функции из за рутины пропустил строчку кода
    после 37 строчки должно быть adc edi,0

    Если это возможно прошу модераторов исправить
    --- Сообщение объединено, 23 мар 2024 ---
    Прошу прощения в четвёртой функции из за рутины пропустил строчку кода
    после 37 строчки должно быть adc edi,0

    Если это возможно прошу модераторов исправить
     
  8. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    в x64 регистров вагон и тележка
    а еще есть XMM/YMM/ZMM!
     
  9. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    94
    В x64 регистров максимум еще один вагон (еще 8 регистров общего назначения), а маленькая тележка это уже SSE3+/AVX/AVX512

    Я вот тоже в своем примере пропустил одну строчку. Вот исправленный пример
    Код (ASM):
    1.  
    2. .data
    3.   text          db '1234567890123456789', 0
    4. .code
    5.         push    ebx
    6.         push    esi
    7.         push    edi
    8.         lea     ebx, [text]
    9.         xor     ecx, ecx
    10.         xor     esi, esi
    11.         mov     edi, 10
    12.  
    13.   next:
    14.         cmp     byte [ebx], 0 ; Конец строки
    15.         jz      quit
    16.         xchg    eax, esi ; Умножаем старшую 32-разрядную цифру на основание ссч текстового числа
    17.         mul     edi
    18.         xchg    eax, ecx ; Умножаем младшую 32-разрядную цифру на основание ссч текстового числа
    19.         mul     edi
    20.         add     edx, ecx ; Учитываем перенос
    21.         jc      overflow ; Число больше 64 разрядов
    22.         movzx   ecx, byte [ebx]
    23.         xor     esi, esi
    24.         sub     ecx, '0'
    25.         cmp     ecx, edi ; Цифра числа верная (меньше основания ссч)?
    26.         jae     error
    27.         add     ecx, eax ; Складываем умноженное число с новой цифрой из строки
    28.         adc     esi, edx
    29.         inc     ebx
    30.         jnc     next
    31.         dec     ebx
    32.  
    33.   overflow: ; Ошибка в длине числа (превосходит 64 бита)
    34.         push    MB_OK or MB_ICONERROR
    35.         push    error_head
    36.         push    error_text
    37.         push    0
    38.         call    MessageBoxW
    39.         mov     ecx, ebx
    40.         xor     esi, esi
    41.         stc
    42.         jmp     quit
    43.  
    44.   error: ; Ошибка в записи числа
    45.         push    MB_OK or MB_ICONERROR
    46.         push    error_head
    47.         push    error_text2
    48.         push    0
    49.         call    MessageBoxW
    50.         mov     ecx, ebx
    51.         xor     esi, esi
    52.         stc
    53.  
    54.   quit:
    55.         mov     eax, ecx
    56.         mov     edx, esi
    57.         pop     edi
    58.         pop     esi
    59.         pop     ebx
    60.         retn
    61.   error_head    db 'Str2Int', 0
    62.   error_text    db 'Value out of range!', 0
    63.   error_text2   db 'Invalid number!', 0
    64.  
    Теперь при ошибке устанавливается флаг переноса и в eax возвращается указатель на символ с ошибкой.
     
  10. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792
    assch,
    прикрепленному файлу 10 лет :drinks:
     

    Вложения:

    • temp.zip
      Размер файла:
      17,7 КБ
      Просмотров:
      697
    alex_dz нравится это.
  11. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    203
    Спасибо Mikl___, посмотрю