Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Alexeyslav »

В результате выполнения команды, содержимое не изменится. Только установятся флаги.

А в том первоначальном вариенте декремента, с проверкой на минус R1 будет декрементирован и при R0 = -1 и при -2... если его не "обнулить" то максимум за 256 тактов R1 в любом случае досчитает до нуля. получится фигня...

В конечном варианте, все пучком.
Реклама
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение afz »

Alexeyslav писал(а):В результате выполнения команды, содержимое не изменится. Только установятся флаги.

А в том первоначальном вариенте декремента, с проверкой на минус R1 будет декрементирован и при R0 = -1 и при -2... если его не "обнулить" то максимум за 256 тактов R1 в любом случае досчитает до нуля. получится фигня...

В конечном варианте, все пучком.

Угу. Итого.

Код: Выделить всё

    or     r0,r0
    brne 1$
    dec   r1
1$:dec  r0
    or     r0,r1
    breq SecOK ; секунда кончилась

Вывод: не высыпаться - вредно.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Реклама
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Alexeyslav »

У тебя в конце первой же итерации содержимое R0 разрушается, для сравнения с нулем надо какой-то другой регистр использовать чтобы R0 не запортить. Иначе 100% шансов получить бесконечный цикл или очень короткий.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

afz писал(а):aklА теперь, пожалуйста, то же самое для (R0, R1).
X-Y-Z заняты. И R24-R25 трогать нельзя. То есть, конечно, можно сохранить их, а потом восстановить, но меня интересует именно прямой вариант вычислений в (R0, R1)...

У меня получилось как то так. Длинновато, зато работает во всем диапазоне 0...65535. Формат R0:R1 (старший: младший)
Спойлер

Код: Выделить всё

TEST_R0_R1:
   LDI   XH,HIGH(65535)   ; для проверки
   LDI   XL,LOW(65535)   ; для проверки
;   LDI   XH,HIGH(0)   ; для проверки
;   LDI   XL,LOW(0)   ; для проверки
;   LDI   XH,HIGH(2304)   ; для проверки когда младший байт =0
;   LDI   XL,LOW(2304)   ; для проверки когда младший байт =0
   STS   $60,XH
   STS   $61,XL
GO_TEST:   
   LDS   R0,$60      ; для проверки
   LDS   R1,$61      ; для проверки
   LDS   XH,$60      ; для проверки
   LDS   XL,$61      ; для проверки
;*************************************************
   CLR   R3
TEST10:
   SBIW   XL,1      ; для проверки
   
   CPSE   R1,R3
   RJMP   TEST2
   CPSE   R0,R3
   RJMP   TEST0
   RJMP   OUT
TEST0:
   DEC   R0
TEST2:
   DEC   R1
   RJMP    TEST10
OUT:
   RJMP    GO_TEST
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение zero648 »

afz писал(а):А как принято делать двухбайтовые счетчики? Вот мне понадобилось в таймерном прерывании 2400 Гц отсчитать секунду. Я, как на нормальных системах, загрузил в пару регистров 2400 (hi , low), но что-то мне подсказало заглянуть в описание команды DEC. Ага, так и ждал подляны: DEC не взводит бит C. Ну и как прикажете считать? Нет, конечно, мне не составило труда посчитать в одном регистре 100 и во втором 24, но это удобный частный случай, а понадобись посчитать простое число, не влезающее в один регистр, хотя бы 2437 и как тогда принято делать?

Тогда принято первый младший брать с остатком, а старший так и останется, в вашем случае превый младший брать 137, старший 24, остальные младшие грузить по 100, итого 137*1+100*23=2437
Реклама
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Jack_A »

На DEC свет клином не сошелся, команда SUBI Rx,1 делает все то же самое, но при этом изменяет бит С.
Реклама
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

Совершенно верно, но эти команды (SUBI, SBCI) работают только со старшей частью регистрового файла, а afz загнал себя в угол
afz писал(а):X-Y-Z заняты. И R24-R25 трогать нельзя...
и оставил себе только
afz писал(а):вариант вычислений в (R0, R1).

По мне, налицо, неправильное распределение вычислительных возможностей и мощности регистрового файла AVR, приводящее к таким заявлениям
afz писал(а):Блин, ну до чего корявая и дилетантская система команд. 32 общих регистра, да. Нагло врут! ОБЩИХ (действительно общих) регистров всего 6 - R26-R31. Почти общих - еще 2: добавляются R24, R25, с остальными не работают команды ADIW/SBIW. Более-менее общих - еще 8: R16-R23. С остальными R0-R15 не работает половина команд. Бить лицо. Ногами.
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение afz »

Alexeyslav писал(а):У тебя в конце первой же итерации содержимое R0 разрушается, для сравнения с нулем надо какой-то другой регистр использовать чтобы R0 не запортить. Иначе 100% шансов получить бесконечный цикл или очень короткий.

Угу. Я же говорю, не высыпаться вредно. Но смысл ясен.
akl
Не то, чтобы я загнал себя в угол - у меня изначально была частота прерываний 150 Гц, я спокойно считал секунду в R15 и не жужжал. Позже, в попытке приспособить этот же проект для чуть-чуть другой задачи, пришлось поднять частоту прерываний. Для счета секунды я, по-простому, взял второй регистр - R11, посмотрел, что для прямого счета арифметика оказывается какой-то непонятной, сделал в R15 счетчик до 24, а в R11 - до 100, а для прояснения вопроса с арифметикой задал вопрос здесь.

Тема прояснена полностью. Выводы:
- для регистров первой половины регистрового файла не существует решения, использующего менее трех регистров;
- на будущее подобный счетчик следует располагать в R24:R25 или в неиспользуемой паре X-Y-Z;
- ну и на хрена эти R0-R15, если в них ничего хорошего не сделаешь? И кто посмел сказать что они общие?
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Kavka »

А чем предложенное мной и Alexeyslav-ом не подходит? :)
Без дополнительных регистров и не длинно.
R1:R0 - старший:младший

Код: Выделить всё

    tst r0
    brne  L1
    dec r1
L1:
    dec r0
    brne notZero
    cpi r1,0
    brne notZero
Zero:

notZero:
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение afz »

Да все нормально, не считая того, что вместо CPI r1,0 надо писать tst r1. Но, по-любому 7 команд вместо одной sbwi r24,1 - это наглядная демонстрация корявости системы команд. Вот у Системы-360 действительно 16 общих регистров. Или у PDP-11 - 7 общих регистров. Из контроллеров - у MSP-430 тоже общие регистры, точное число не помню, 13 кажется. Но 430-й с самого начала проектировался с оглядкой на PDP-11. А у AVR - пшик, а не общие регистры. Или взять команды SBI/CBI. Готовлю к работе таймер 0, взвести бит TOIE0 в порту TIMSK - сам Бог велел использовать команду SBI. Ага, щаззз! Operand 1 out of range. Оказывается, TIMSK Оказывается, адрес TIMSK больше, чем 0x1F. Регистр, состоящий из отдельных битов, которыми надо управлять по-отдельности, расположен в недоступной для SBI/CBI зоне. Это хорошая система команд, да?

Я бы, при проектировании такого процессора плюнул на байтовую организацию программной памяти и сделал командное слово шириной битов 20, и все бы сошлось - для Гарвардской архитектуры это вполне допустимо, память данных байтовая, а как там выглядит командное слово - дело 25-е.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Kavka »

Только tst r1 (r0 уже проверен, после dec r0)
В данном случае (проверка на равенство нулю) никакой разницы:
cpi r1,0
tst r1
or r1,r1
and r1,r1
Более того, tst и and, в данном случае, будут иметь одинаковый машинный код.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Kavka писал(а):Gudd-Head, то что в ОЗУ получилось это то что ты хотел? Или я неправильно понял постановку задачи?

Похоже да. Фантастика :) Даже не жо конца догоняю как это работает. Сдвигается через удвоение посредством сложения с частью исходного байта?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Kavka »

Ага. Свойство такое у двоичного представления получается. Вот, как-то так.
Спойлер

Код: Выделить всё

mask[]={0b11111111,0b11111110,0b11111100,0b11111000,0b11110000,0b11100000,0b11000000,0b10000000};
F = ( (x & mask[pos]) << 1 ) | (x & ~mask[pos])
L = (x & mask[pos]) << 1 )
R = (x & ~mask[pos])
F = L  |  R

XM = x & mask[pos], тогда L = XM << 1 = XM * 2 = XM + XM

очевидно, что XM | R = XM + R = x

Соберая всё. Получаем: F = L + R = XM + XM + R  =  XM + x = (x & mask[pos]) + x
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Jack_A »

akl писал(а):Совершенно верно, но эти команды (SUBI, SBCI) работают только со старшей частью регистрового файла


Совершенно верно, но если , к примеру, SBIW работает только с одной из четырех регистровых пар, то SUBI, SBCI - с любыми 16 старшими регистрами, причем не обязательно рядом расположенными, и если грамотно распорядиться ресурсами, не придется выдумывать сложные извраты с длинными числами. Создаем себе проблему, а потом ее героически борем -- это так по-нашему.
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3870
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Engineer_Keen »

Jack_A писал(а):Создаем себе проблему, а потом ее героически борем -- это так по-нашему.

Дело опыта. Я когда с mcs51 перелезал по началу ругался на систему команд авр (нельзя напрямую отдельные биты копировать, для разных типов памяти разные команды, нельзя за одну команду сравнить и сделать переход и т.д.), а потом как разобрался, обратно не хочется возвращаться, хотя по работе иногда нужно :)
Аватара пользователя
Jurkin
Вымогатель припоя
Сообщения: 515
Зарегистрирован: Вт янв 01, 2013 15:51:19
Откуда: Vilnius

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Jurkin »

Gudd-Head писал(а):Похоже да. Фантастика :) Даже не жо конца догоняю как это работает. Сдвигается через удвоение посредством сложения с частью исходного байта?

...нда, кодик выглядит симпотно и даже ПОЧТИ рабочий ;) , но увы, не со всеми данными правильно работает. К примеру возьмите $77, часть корректно сдвигает/вставляет, а часть нет ....ну или я не правильно понял условия задачи...
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Прогнал.
Изображение
В первом байте ноль вставлен в конец, 1110111 (0х77) сдвинулось влево и получилось 0b11101110.
Во втором байте ноль влез во второй бит, получилось 0b11101101.
....
под конец получили исходное 0b01110111. Видно как нолик двигается справа налево:
0b11101110 EE
0b11101101 ED
0b11101011 EB
0b11100111 E7
0b11100111 E7
0b11010111 D7
0b10110111 B7
0b01110111 77
Думаю, если заполнять маску наоборот единицами, то получим нужный порядок. Но можно и этим обойтись.
Вложения
Безымянный.GIF
(1.88 КБ) 532 скачивания
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Jurkin
Вымогатель припоя
Сообщения: 515
Зарегистрирован: Вт янв 01, 2013 15:51:19
Откуда: Vilnius

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Jurkin »

...вообщет да, всё похоже очень даже не плохо ..по ходу я стормозил :oops:
респект Kavka :beer:
SmarTrunk
Друг Кота
Сообщения: 6014
Зарегистрирован: Чт ноя 26, 2009 11:16:50
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение SmarTrunk »

afz писал(а):Я бы, при проектировании такого процессора плюнул на байтовую организацию программной памяти и сделал командное слово шириной битов 20
Я тоже об этом думал. Добавили бы пару битов - и система команд сразу стала бы приятнее. Но мне-то приходилось программировать и i8048, а после этого АВР - сказка. Еще, может, они думали, что все на Си будут писать, а уж компилятор со всем разберется.
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Kavka »

Если ещё остались не "въехавшие" :) - проверьте перебором.
Спойлер

Код: Выделить всё

#include <stdio.h>

unsigned char mask[]={0b11111111,0b11111110,0b11111100,0b11111000,0b11110000,0b11100000,0b11000000,0b10000000};

// вариант с двумя масками (прямой и инверсной)
unsigned char izb(unsigned char x,unsigned char pos) {
    return ( ( (x & mask[pos]) << 1 ) | (x & ~mask[pos]) );
}

// вариант со сложением
unsigned char izb2(unsigned char x,unsigned char pos) {
    return ( x + (x & mask[pos]) );
}

void main() {

int i,j;
unsigned char t1,t2;

  for (i=0; i<256; i++) {
    for (j=0; j<8; j++) {
      t1 = izb(i,j);
      t2 = izb2(i,j);
      if ( t1 != t2 ) {
        printf("Error\n");
      }
    }
  }

}
:))) Не забываем ставить плюсы.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Ответить

Вернуться в «AVR»