А не пошлЮт...
Это, конечно понятно, что двигать регистр более чем на его разрядность бессмысленно. В циклических сдвигах это эквивалентно (N mod 32) или (N mod 33). В нециклических сдвигах, при сдвиге на значение, превышаюшее разрядность, происходит обнуление.
Интересно, что там Интеловцы про синус придумали. Тоже, наверное, остаток от деления аргумента на 2Пи используют.
Мне помнится, как только вышли процессоры, которые за 1 такт инструкции типа перемещения, сложения и др. выполняли, а умножали за несколько десятков тактов, я пытался с АМДшниками связаться, предложить конструктив умножения за несколько тактов. Что-то так и не вышло. А современные Атлончики и так умножать умеют за один такт, надеюсь.
Скомпилил Симантеком - выдала 1, скомпилил стареньким Борландом - выдала 0, то же с ключиком -3 - выдала 1.
Выводы - в библиотечке для 286 двигается 32 раза, а сам поцессор (проверял на Атлоне и P-III) реагирует только на 4 младших бита.
Интересно - что на самом деле должно быть (по стандарту)?
Оказывается, это не баг, а фича Intel. Реально инструкция SHL и SHR делает сдвиг на (N mod _разрядность сдвигаемого регистра_).11.02.04 13:08 Автор: HandleX <Александр М.> Статус: The Elderman
Дополнительные исследования показали, что…11.02.04 13:35 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 11.02.04 13:37 Количество правок: 1
Итак, цикличность сдвига равна 32 и не зависит от разрядности сдвигаемого регистра. Интересно, как поведёт себя это дело на IA64? Скорее всего она станет равна 64. Так что делайте выводы.
А ты попробуй printf("%ld\n", l)10.02.04 16:15 Автор: SL Статус: Незарегистрированный пользователь
Во первых в современных компилерах int и так имеет размер 32 бита (а %d - печатает именно int). Во вторых после смещения на 32 все равно 0 везде должен остаться. В третьих даже в 16-битных компилерах в little-endian архитектурах единица вылезет в старшие разряды, которые идут в памяти после младших. То бишь скорее %ld будет не нулем, чем %d
ИМХО это именно глюк
Блин, сразу не смекнул.11.02.04 11:56 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> Во первых в современных компилерах int и так имеет размер > 32 бита (а %d - печатает именно int). Во вторых после > смещения на 32 все равно 0 везде должен остаться. В третьих > даже в 16-битных компилерах в little-endian архитектурах > единица вылезет в старшие разряды, которые идут в памяти > после младших. То бишь скорее %ld будет не нулем, чем %d > > ИМХО это именно глюк Попробовал Борландом 3.1, все равно 0.
Все-таки библиотека, скорее всего честно двигает 32 раза, ну да это не важно. Обидно, что проц не сдвинул 32 раза, а нигде это не написано.
Как раз про проц-то все написано. А вот про глюк компиляторов - нет.14.02.04 04:17 Автор: AlexD <Alexander> Статус: Member
Имелось ввиду imho следующее: вполне логично, что сдвиг мпилятор переводит и интеловскую инструкцию shl. Так вот, её второй операнд может иметь величину от 0 до 31 включительно(кажись как раз начиная с 386-х это и изменили). Соответственно на процах выше 286 инструкция shl <lya-lya>, 32 равносильна nop - ничего не делающей операции. Поэтому мы и получаем 1. На 286 же вроде не было такого ограничения(или на 8086 :-)? ) - и там выполняется полный сдвиг на 32....т.е. получаем 0. Так что, видимо, ни от каких библиотек это не зависит... Просто писатели компиляторов не учли платформно-зависимый прикол от интела...
Интересно на 386 и 486 проверить было, может там напрямую...11.02.04 12:05 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman Отредактировано 11.02.04 12:06 Количество правок: 1
> включительно(кажись как раз начиная с 386-х это и
Интересно на 386 и 486 проверить было бы, может там напрямую двигали, с использованием регистра сдвига и счетчика.
> изменили). Соответственно на процах выше 286 инструкция shl > <lya-lya>, 32 равносильна nop - ничего не делающей > операции. Поэтому мы и получаем 1. На 286 же вроде не было > такого ограничения(или на 8086 :-)? ) - и там выполняется > полный сдвиг на 32....т.е. получаем 0. Так что, видимо, ни > от каких библиотек это не зависит... Просто писатели
Раз уж в 286 нет инструкции сдвига 32 битного целого, похоже компилер генерит вызов встроенной функции.
> компиляторов не учли платформно-зависимый прикол от > интела...
Мне кажется так: в 286 нет 32-битных целых, но есть сдвиг на любое число от 0 до 25514.02.04 04:15 Автор: AlexD <Alexander> Статус: Member
> Интересно - что на самом деле должно быть (по стандарту)? По стандарту << - операция сдвига, а не ротации. Так что единица не должна была вернуться в нулевой разряд никаким макаром. В общем 0 должен быть
Сдвиг (<< или shl) не циклический (rol или rcl). Скорее...11.02.04 11:42 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
> По стандарту << - операция сдвига, а не ротации. Так > что единица не должна была вернуться в нулевой разряд > никаким макаром. В общем 0 должен быть Сдвиг (<< или shl) не циклический (rol или rcl). Скорее всего проц посмотрел на младшие 4 разряда (а они все нули) и ничего не сдвинул.
Может там че-то с интерпретацией carry flag компилером?10.02.04 15:21 Автор: whiletrue <Роман> Статус: Elderman Отредактировано 10.02.04 15:24 Количество правок: 2
Гы-ыыы! А вы попробуйте вот что... Всё-таки цикличность явно наблюдается... (updated)11.02.04 12:36 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 11.02.04 12:46 Количество правок: 2
--- В общем, возвращает она 8. А если сдвигать на 34 бита, то EAX=4. А если на 33 бита, то EAX=2. Ну и надо думать, что сдвиг на 32 бита даёт единицу.
Вообще, если в регистр занести любое значение и выполнить SHL регистр, 32, то значение регистра не изменится! -- Begin update --
О! значение регистра не меняется, если делать его сдвиг на 32 * N, где N — целое число... Причёи направление сдвига неважно — это может быть и SHR! ;-)
-- End update --
Странно, что об этом нигде не написано...
А rol, ror, rcl, rcr никто не прбовал?11.02.04 14:55 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
Абсолютно то же с ROL и ROR, RCR и RCL (внутри)11.02.04 15:06 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 11.02.04 15:41 Количество правок: 2
Ваши предположения правильные — в регистре будет число 7777!
Ни одна из инструкций после MOV не изменила содержимое EAX (проверял отладчиком).
Вывод — IA32 в вышеуказанных инструкциях использует только младшие 5 бит во втором операнде (на сколько двигать), всё остальное отбрасывает.
Кста, на AMD тоже самое. Я думаю, это описано в спецификациях Intel, лезть на их сайт неохота ;-)
А мое сообщение повыше не пробовал читать:)? Я и написал, что написано в спецификации14.02.04 04:19 Автор: AlexD <Alexander> Статус: Member