В edx:eax лежит 64-битное беззнаковое целое. Как можно реализовать сдвиг этого числа на ecx битов? MMX/SSE не годятся, т. к. нужно контролировать переполнение
Вправо: shrd eax,edx,cl shr edx,cl Влево: shld edx,eax,cl shl eax,cl Правда переполнение так не поймаешь
Loger Для случая ecx>31 можно так: shr edx,cl mov eax,edx xor edx,edx shl eax,cl mov edx,eax xor eax,eax И для случая ecx>=64 тоже специальный вариант. Другое в голову что-то не приходит.
Вариант для сдвига влево. Вправо можно сделать аналогично заменив ротации и сдвиг на противоположные, и убрать инструкции test+jnz, поскольку там переполнение видимо (?) не грозит. Код (Text): or ebx,-1 ;mov esi, ebx mov edi, ebx rol edx, cl rol eax, cl shl ebx, cl xor edi, ebx ;xor esi, ebx test edi, edx; and esi, edx jnz overflow and edx, ebx and edi, eax and eax, ebx or edx, edi Это для случаев ecx<32, для больших, как предлагает Artem. Если же ecx>=64, очевидно будет переполнение. PS Может лучше всё же через MMX, а переполнение отдельно проверить? PSS Вот ещё, под условия не подходит, но может пригодится 64-bit integer math PSSS подправил немного код, а то большой слишком был
может, так? влево Код (Text): @@: sal eax,1 rcl edx jc переполнение loop @B или до того как переполнение возникнет (старший бит еще не попал в С Код (Text): @@: test edx,10000000h jnz переполнение sal eax,1 rcl edx loop @B
shoo Разве старший бит - это не 80000000h? Проверять его можно короче Код (Text): test edx,edx js переполнение или Код (Text): or edx,edx js переполнение
imho, лучше не юзайть всякие shrd и loop, они любой пень превращают в 486.. Разве что когда размер очень критичен.
1. насчет 10000000 прогнал спросоня 2. насчет оптимальности - не возражаю, только не так - "вот очень оптимальный код, только то что нужно - не делает" пс - а я всегда думал, что ор и энд обнуляют перенос ?
не, это из опыта - бывает че-нибудь пишешь и сразу хочется пооптимальней, а потом дундохаешься, пока в отладчике по шагам не отловишь
rol edx, cl rol eax, cl shl ebx, cl здесь, по-моему, как минимум cl восстанавливать надо в промежутках
да, глянул - можно or edx,edx, а потом js ... пс: глянул еще - хе-хе, с моими настройками баузера код выглядит мелким, так что я js с jc перепутал - неуглядел псс: ужо браузер перестроил, чтобы казусов не было
shoo > Зачем? Он же не меняется. Мой код вполне рабочий для cl до 31 включительно, на K7 и P6 это быстрее чем shld и учитывает перенос. Для бОльших значений лучше использовать код Artem, добавив проверку на переполнение: Код (Text): test edx,edx jnz overflow shl eax,cl mov edx,eax xor eax,eax