Ваша цель - получить следующие значения:
255 = 0xFF = 11111111
254 = 0xFE = 11111110
253 = 0xFD = 11111101
251 = 0xFB = 11111011
Но вы используете инструкцию rol
, которая сдвигает ваш регистр на 1 и добавляет перенос. Кэрри все время равен нулю, поэтому вы всегда добавляете ноль. Это приводит к следующим значениям:
255 = 0xFF = 11111111
254 = 0xFE = 11111110
252 = 0xFC = 11111100
248 = 0xF8 = 11111000
«Проблема» состоит в том, что инструкция cp
также использует бит переноса, поэтому он очищает бит переноса, потому что операция r18
минус r17
не устанавливает перенос (ваш cp r18, r17
). Ваш код работает без cp
, потому что перенос не очищается в любое время.
Одним из возможных решений является использование cpi
перед вызовом вашего rol
:
cpi r16, 255
rol r16
Теперь ваш перенос будет установлен, когда содержание r16
ниже 255
, (cpi
выполняет операцию r16
- 255
). Керри будет использоваться вашим rol
, и вы получите правильный результат. Один положительный аспект заключается в том, что для решения требуется только один дополнительный такт на цикл, поэтому он немного умнее, чем инструкция перехода или что-то еще.