AVR Assembler: разложение числа на цифры

Здравствуйте! Имеется ATMega128 и 8-разрядный регистр r16, в котором находится число от 0 до 255. Нужно получить регистры r17, r18, r19, в которых будут содержаться цифры числа из r16. Как лучше сделать, в какую сторону копать? Предполагаю, нужно воспользоваться деление с остатком. Сначала r16 делить на 100, записать первый разряд, потом остаток делить на 10 — записать второй разряд, и, наконец, конечный остаток записать в третий разряд. Но тут уже возникает другой вопрос — как разделить с остатком? Заранее спасибо.
  • Вопрос задан
  • 7496 просмотров
Решения вопроса 1
apangin
@apangin
На AVR никогда не программировал, поэтому ограничусь алгоритмом.

1 способ, короткий.
    while (r16 >= 100) { r17++; r16 -= 100; }
    while (r16 >= 10)  { r18++; r16 -= 10; }
    r19 = r16;

2 способ, быстрый.
    if (r16 >= 200) {
      r17 = 2;
      r16 -= 200;
    } else if (r16 >= 100) {
      r17 = 1;
      r16 -= 100;
    }
    if (r16 >= 50) { r18  = 5; r16 -= 50; }
    if (r16 >= 20) { r18 += 2; r16 -= 20; }
    if (r16 >= 20) { r18 += 2; r16 -= 20; }
    if (r16 >= 10) { r18++;    r16 -= 10; }
    r19 = r16;

3 способ, если чип поддерживает инструкцию MUL.
Воспользоваться тем, что (N / 10) = Hi(N * 0xCD) >> 3;
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
ertaquo
@ertaquo
Сорри, с этим ассемблером не работал… Но так понимаю, что если есть деление без остатка, то остаток от деления можно получить примерно так: num — (num div 10) * 10
Ответ написан
Sannis
@Sannis
Если у вас число ограничено 255, то можно использовать условия и битовые сдвиги. Немного длинно, но наверняка. И быстрее, чем на 10(100) делить.
Ответ написан
etc
@etc Автор вопроса
Спасибо apangin за интересный алгоритм.

Сегодня задал этот вопрос преподавателю. Получил в ответ похожий алгоритм:

while (r16 > 0) {
if (r19 == 9) {
r18++;
r19 = 0;
}
if (r18 == 9) {
r17++;
r18 = 0;
}
r19++;
r16--;
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы