Сдвиг (длинная арифметика)

Тема в разделе "WASM.ASSEMBLER", создана пользователем Loger, 18 авг 2004.

  1. Loger

    Loger New Member

    Публикаций:
    0
    Регистрация:
    28 авг 2003
    Сообщения:
    71
    Адрес:
    Minsk
    В edx:eax лежит 64-битное беззнаковое целое. Как можно реализовать сдвиг этого числа на ecx битов? MMX/SSE не годятся, т. к. нужно контролировать переполнение
     
  2. Artem

    Artem New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2003
    Сообщения:
    29
    Адрес:
    Russia
    Вправо:

    shrd eax,edx,cl

    shr edx,cl



    Влево:

    shld edx,eax,cl

    shl eax,cl



    Правда переполнение так не поймаешь
     
  3. Loger

    Loger New Member

    Публикаций:
    0
    Регистрация:
    28 авг 2003
    Сообщения:
    71
    Адрес:
    Minsk
    Artem

    У этого способа есть недостаток: при ecx>31 он работает неправильно
     
  4. Artem

    Artem New Member

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



    Для случая ecx>31 можно так:



    shr edx,cl

    mov eax,edx

    xor edx,edx



    shl eax,cl

    mov edx,eax

    xor eax,eax



    И для случая ecx>=64 тоже специальный вариант. Другое в голову что-то не приходит.
     
  5. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    shl+rcl/shr+rcr ?
     
  6. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Вариант для сдвига влево. Вправо можно сделать аналогично заменив ротации и сдвиг на противоположные, и убрать инструкции test+jnz, поскольку там переполнение видимо (?) не грозит.


    Код (Text):
    1. or   ebx,-1
    2. ;mov  esi, ebx
    3. mov  edi, ebx
    4.  
    5. rol  edx, cl
    6. rol  eax, cl
    7. shl  ebx, cl
    8.  
    9. xor  edi, ebx
    10. ;xor  esi, ebx
    11.  
    12. test edi, edx; and  esi, edx
    13. jnz  overflow
    14.  
    15. and  edx, ebx
    16. and  edi, eax
    17. and  eax, ebx
    18.  
    19. or   edx, edi




    Это для случаев ecx<32, для больших, как предлагает Artem.

    Если же ecx>=64, очевидно будет переполнение.





    PS

    Может лучше всё же через MMX, а переполнение отдельно проверить?





    PSS

    Вот ещё, под условия не подходит, но может пригодится 64-bit integer math



    PSSS

    подправил немного код, а то большой слишком был
     
  7. shoo

    shoo New Member

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



    влево
    Код (Text):
    1.  
    2. @@:
    3. sal eax,1
    4. rcl edx
    5. jc переполнение
    6. loop @B
    7.  




    или до того как переполнение возникнет (старший бит еще не попал в С


    Код (Text):
    1.  
    2. @@:
    3. test edx,10000000h
    4. jnz переполнение
    5. sal eax,1
    6. rcl edx
    7. loop @B
    8.  
     
  8. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    shoo

    Разве старший бит - это не 80000000h?

    Проверять его можно короче
    Код (Text):
    1. test edx,edx
    2. js переполнение
    или
    Код (Text):
    1. or edx,edx
    2. js переполнение
     
  9. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    imho, лучше не юзайть всякие shrd и loop, они любой пень превращают в 486..

    Разве что когда размер очень критичен.
     
  10. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    1. насчет 10000000 прогнал спросоня ;)

    2. насчет оптимальности - не возражаю, только не так - "вот очень оптимальный код, только то что нужно - не делает" ;)



    пс - а я всегда думал, что ор и энд обнуляют перенос ?
     
  11. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    shoo

    2 ... только не так

    Это в мой адрес?
     
  12. shoo

    shoo New Member

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

    shoo New Member

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

    rol eax, cl

    shl ebx, cl



    здесь, по-моему, как минимум cl восстанавливать надо в промежутках
     
  14. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    да, глянул - можно or edx,edx, а потом js ...



    пс: глянул еще - хе-хе, с моими настройками баузера код выглядит мелким, так что я js с jc перепутал - неуглядел ;)



    псс: ужо браузер перестроил, чтобы казусов не было ;)
     
  15. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    shoo >







    Зачем? Он же не меняется.

    Мой код вполне рабочий для cl до 31 включительно, на K7 и P6 это быстрее чем shld и учитывает перенос.



    Для бОльших значений лучше использовать код Artem, добавив проверку на переполнение:
    Код (Text):
    1. test edx,edx
    2. jnz overflow
    3.  
    4. shl eax,cl
    5. mov edx,eax
    6. xor eax,eax