Скомпилил Симантеком - выдала 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