Sergei Troizky
17.03.2020 - 03:17
Столкнулся с необходимостью эмулировать инструкцию MVM (move with mask) из Allen Bradley.
Инструкция [MVM S M D] копирует из регистра S в регистр D биты,
соответствующие включенным битам регистра-маски M, не затрагивая остальных битов в D.
Решение получилось неожиданно громоздким: 4 инструкции и вспомогательный регистр.
Сможет ли кто-нибудь предложить решение с меньшим количеством инструкций?
WAND - для обнуления бит
WOR - для установки бит
Для вашего случая
WOR S k4M D
Sergei Troizky
17.03.2020 - 15:38
Торопитесь. Либо неверно поняли задание.
Биты, указанные маской, должны быть СКОПИРОВАНЫ из источника в получатель.
Ваше решение неверно: активные биты в получателе останутся включенными,
а не скопированными из источника, если там были выключены.
не верно воспринял задание ...
таблицу истинности бы тогда
вход 1001
маска 1100
выход тек. 0110
должно стать ??
Sergei Troizky
17.03.2020 - 23:46
Цитата(m_by @ 17.03.2020 - 17:15)
не верно воспринял задание ...
таблицу истинности бы тогда
вход 1001
маска 1100
выход тек. 0110
должно стать ??
Должно стать 1010.
Первые два бита, указанные маской, скопированы из источника.
Вторые два остались в получателе незатронутыми.
тогда ваш способ похоже правильный
- получить обратную маску
- очистка выходного регистра по обратной маске
- маскирование входного слова
- объединение результатов
Sergei Troizky
18.03.2020 - 17:51
Он правильный без "похоже", т.к. работает.
Интересно было бы найти более компактное решение, по количеству инструкций.
А какой контроллер ?
Можно реализовать через цикл обхода по битам,
только когда так делал последний раз - время выполнения программы утроилось ((.
Sergei Troizky
20.03.2020 - 22:14
Модель (и даже производитель) контроллера непринципиальны.
Подразумевается лишь отсутствие в нем такой инструкции.
Задача интересна с алгоритмической точки зрения и ясно сформулирована на предмет сокращения кода.
Любой код цикла будет не короче 4-х инструкций, т.к. 3 инструкции необходимы лишь для организации самого цикла.
inntele
25.03.2020 - 09:34
Код
WOR M D D
WXOR M D D
WOR S D D
acoustik
25.03.2020 - 10:14
Цитата(inntele @ 25.03.2020 - 15:34)
Код
WOR M D D
WXOR M D D
WOR S D D
На выходе будет 1011
Должно быть 1010
inntele
25.03.2020 - 11:42
Цитата(acoustik @ 25.03.2020 - 11:14)
Цитата(inntele @ 25.03.2020 - 15:34)
Код
WOR M D D
WXOR M D D
WOR S D D
На выходе будет 1011
Должно быть 1010
Конечно. Это лишь повод тщательнЕе подзадуматься над реализацией. Но у задачи явно короткое решение.
inntele
25.03.2020 - 12:13
Код
WOR M D D
WAND M S T
WXOR T D D
WXOR M D D
, где T - промежуточный регистр вычислений
Sergei Troizky
26.03.2020 - 22:37
Цитата(inntele @ 25.03.2020 - 12:13)
Код
WOR M D D
WAND M S T
WXOR T D D
WXOR M D D
, где T - промежуточный регистр вычислений
Увы, по-прежнему 4 инструкции. Правда, иначе, чем у меня.
Похоже, короче не сделать.
Мой вариант (на мой взгляд, чуть нагляднее для понимания):
WXOR M #FFFF T
WAND D T D
WAND S M T
WOR D T D
inntele
27.03.2020 - 07:35
Цитата(Sergei Troizky @ 26.03.2020 - 23:37)
Похоже, короче не сделать.
Мой вариант (на мой взгляд, чуть нагляднее для понимания):
Да, практическая реализация может разниться, тем не менее, метода (алгоритм) у них едина и меньше, чем за четыре команды, нереализуема. Отличие Вашего кода от моего заключается лишь в том, что Вы предустанавливаете маскируемые биты в слове назначения нулями, я же единицами и после перезаписи эти биты инвертирую.
inntele
27.03.2020 - 13:33
К слову, Сергей, наиболее "округлый" код мог бы быть представлен следующим образом:
Код
WOR M D D ; маскируемые биты слова назначения устанавливаем в "1",
WXOR M D D ; следом перезаписываем их же в "0",
WAND S M T ; выдёргиваем из слова источника значения маскируемых бит
WOR T D D ; и перезаписываем их в слово назначения.
Sergei Troizky
28.05.2020 - 00:12
Интуитивно чувствовал, что возможно решение в 3 шага.
Вот оно:
WXOR S D T 'T показывает все биты, различающиеся в S и D. Лишь они (но не обязательно все они) могут потребовать изменения в D.
WAND T M T 'Теперь T показывает только те биты, которые нужно изменить в D.
WXOR D T D 'Изменяем их в D.
Такое решение хорошо еще и тем, что D изменяется в один прием, без промежуточных изменений.
Это может иметь значение, если результат используется в прерывании.
inntele
28.05.2020 - 16:58
Цитата(Sergei Troizky @ 28.05.2020 - 01:12)
Интуитивно чувствовал, что возможно решение в 3 шага.
Красиво)