· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Сдвиг (длинная арифметика)

Посл.отвђт Сообщенiе


Дата: Авг 18, 2004 21:22:19

В edx:eax лежит 64-битное беззнаковое целое. Как можно реализовать сдвиг этого числа на ecx битов? MMX/SSE не годятся, т. к. нужно контролировать переполнение


Дата: Авг 18, 2004 22:01:28 · Поправил: Artem

Вправо:
shrd eax,edx,cl
shr edx,cl

Влево:
shld edx,eax,cl
shl eax,cl

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


Дата: Авг 18, 2004 22:05:40

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


Дата: Авг 18, 2004 22:18:24 · Поправил: Artem

Loger

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

shr edx,cl
mov eax,edx
xor edx,edx

shl eax,cl
mov edx,eax
xor eax,eax

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


Дата: Авг 19, 2004 02:14:46

shl+rcl/shr+rcr ?


Дата: Авг 19, 2004 05:21:25 · Поправил: S_T_A_S_

Вариант для сдвига влево. Вправо можно сделать аналогично заменив ротации и сдвиг на противоположные, и убрать инструкции test+jnz, поскольку там переполнение видимо (?) не грозит.
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
подправил немного код, а то большой слишком был


Дата: Авг 19, 2004 06:27:29 · Поправил: shoo

может, так?

влево
@@:
sal eax,1
rcl edx
jc переполнение
loop @B


или до того как переполнение возникнет (старший бит еще не попал в С
@@:
test edx,10000000h
jnz переполнение
sal eax,1
rcl edx
loop @B


Дата: Авг 19, 2004 06:36:13 · Поправил: q_q

shoo
Разве старший бит - это не 80000000h?
Проверять его можно короче
test edx,edx
js переполнение
или
or edx,edx
js переполнение


Дата: Авг 19, 2004 07:42:17

imho, лучше не юзайть всякие shrd и loop, они любой пень превращают в 486..
Разве что когда размер очень критичен.


Дата: Авг 19, 2004 09:05:24 · Поправил: shoo

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

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


Дата: Авг 19, 2004 09:14:11

shoo
2 ... только не так
Это в мой адрес?


Дата: Авг 19, 2004 09:41:39

не, это из опыта - бывает че-нибудь пишешь и сразу хочется пооптимальней, а потом дундохаешься, пока в отладчике по шагам не отловишь ;)


Дата: Авг 19, 2004 09:51:55

rol edx, cl
rol eax, cl
shl ebx, cl

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


Дата: Авг 19, 2004 10:32:03 · Поправил: shoo

да, глянул - можно or edx,edx, а потом js ...

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

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


Дата: Авг 19, 2004 22:35:02

shoo >

„rol edx, cl
rol eax, cl
shl ebx, cl

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


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

Для бОльших значений лучше использовать код Artem, добавив проверку на переполнение:
test edx,edx
jnz overflow

shl eax,cl
mov edx,eax
xor eax,eax


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.055