Сборка AVR - проблема с поворотом регистра после сравнения - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь написать некоторый код на ассемблере, но не могу решить проблему использования команд ror, rol после команд cpi, cp. Я застрял на нем некоторое время и не могу ничего найти. У меня есть какой-то старый код, когда я использовал cpi, затем перешел в другую ветку программы, выполнил несколько инструкций, и последний из них был вращением без проблем. Я попытался добавить некоторые инструкции перед поворотом, если это что-то изменило, и это не помогло. Моя цель - получить в r16 значения c 254,253,251 et c .. Просто поверните содержимое регистра. Вместо этого я получаю 254,252,248. Если я не использую cp или cpi, проблема не возникает. Я новичок ie в программировании asm, так что извините, если это действительно тупой вопрос. Код ниже - это упрощение того, что мне нужно, потому что я работаю с пользовательским вводом, поэтому половина кода просто предназначена для имитации той же функции программы.

ldi r16,0b11111111
    ldi r17,0b00000001
    ldi r18,0b00000001
    ldi r20,0b00000000
start:
    cp r18,r17
    breq loop
loop:
    inc r20
    rol r16
    rjmp start

1 Ответ

1 голос
/ 03 апреля 2020

Ваша цель - получить следующие значения:

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, и вы получите правильный результат. Один положительный аспект заключается в том, что для решения требуется только один дополнительный такт на цикл, поэтому он немного умнее, чем инструкция перехода или что-то еще.

...