Почему операции Shift и Rotate не работают на обучающем наборе 8086?

Я немного кодировал 8086 обучающий комплект. По какой-то причине SHR,SHL,SAL,SAR,ROL,ROR операции на нем не работают. если я напишу заявление вроде

MOV AX,16
SHR AX,2

он застрянет в строке SHR AX,2, как если бы произошла синтаксическая ошибка. То же самое и с другими операциями сдвига и поворота.

единственный способ заставить его работать - использовать регистр CL.

когда я изменил код на

MOV AX,16
MOV CL,2
SHR AX,CL

он выполнил, но значение в AX должно было быть 4 вместо 5.

также для этого кода

  MOV AX,32
  MOV CL,2
  SHR AX,CL

Значение в AX было 12, но должно было быть 8.

что здесь происходит? Я что-то не так делаю?

ПРИМЕЧАНИЕ: пожалуйста, не говорите мне использовать DIV & MUL вместо операции сдвига, потому что это становится очень сложным при использовании в больших программах.


person Adarsh D    schedule 03.04.2019    source источник
comment
У 8086 не было сдвигов сразу ›1. Величина сдвига должна быть равной 1 или cl.   -  person Michael    schedule 03.04.2019
comment
Что касается ваших результатов: 32h ›› 2 = 12 и 16h ›› 2 = 5. Таким образом, похоже, что ассемблер, который вы используете по умолчанию, интерпретирует непосредственные выражения в базе 16.   -  person Michael    schedule 03.04.2019
comment
@Michael: Интересно, это DEBUG.EXE? Я думал, что все остальные ассемблеры x86 по умолчанию используют десятичный формат. Но я не думаю, что это не объясняет отказ от инструкций 186 и 286 по умолчанию. Может быть, у emu8086 есть настройка для этого, или, может быть, он работает по умолчанию, и он никогда раньше не поднимался в вопросе SO?   -  person Peter Cordes    schedule 03.04.2019


Ответы (3)


Что касается второй части вашего вопроса, как только вы собрали его и получили 16 >> 2 = 5, когда вы ожидали 4:

Это потому, что ваш ассемблер обрабатывает все числа как HEX (основание 16).

Если у вас 16 шестнадцатеричный, это двоичный 0001 0110, если сдвинуть 2 раза, получится
0000 0101, и это 5,
0 = 8, 1= 4, 0=2, 1=1

0x16 >> 2 = 5

поэтому вам нужно указать 16 десятичных оснований
или работать с шестнадцатеричным основанием

0x16 = 22. Если вы хотите десятичное 16, это 10 в шестнадцатеричном формате.

person Black Hole    schedule 03.04.2019
comment
Я говорю о количестве AX, а не о сдвиге, в CL вы указываете номер сдвига, если он больше 1, это правильно, но почему результат 16 shr 2 равен 5, а не 4, потому что основание числа, результат правильный, логики нет, я говорю о другом. - person Black Hole; 03.04.2019
comment
@DavidHoelzer: это только ответ на вторую половину вопроса, примерно 4 против 5, но на самом деле это правильно. Я отредактировал его, чтобы уточнить. - person Peter Cordes; 03.04.2019

он застрянет в строке SHR AX,2, как если бы произошла синтаксическая ошибка. То же самое и с другими операциями сдвига и поворота.

Как указано в справочнике инструкций NASM, SHR с операндом счетчика немедленных сдвигов представляет собой инструкцию 186+. Поскольку вы, похоже, используете emu8086, он не поддерживается вашим ассемблером и целевой машиной.

См. https://ulukai.org/ecm/insref.htm#insSHL.

8086 имеет только коды операций машинного кода для сдвигов на cl и сдвигов на неявное 1. Запись shr ax,1 преобразуется в инструкцию без немедленного выполнения, только код операции для сдвига на неявный счетчик 1.

Другие подсчеты не поддерживаются, потому что до 186 нет доступной кодировки.

Вы можете сдвинуть на 2, используя shr дважды, или для большего количества на mov cl, 7 / shr ax, cl. (Для большого количества, такого как 8, может быть быстрее mov al, ah / mov ah,0 на реальном 8086, где каждый счет сдвига требует дополнительного цикла.)

person ecm    schedule 21.07.2019

когда выполняется такая операция, как MOV AX,16, значение внутри отображается как 0000 0000 0001 0110. так что содержимое регистра AX теперь 0000 0000 0001 0110.

поэтому, когда выполняется операция сдвига SHR AX,CL, где CL равно 2, тогда значение в AX станет 0000 0000 0000 0101, что равно 5.

Вот почему

MOV AX,16 MOV CL,2 SHR AX,CL

дал 5 после смены.

person Adarsh D    schedule 05.04.2019
comment
спасибо, @Peter Cordes за помощь в подведении итогов - person Adarsh D; 05.04.2019