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

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Аватара пользователя
Сообщения: 526
Зарегистрирован: Вс дек 28, 2014 18:35:34
Откуда: Луганск

Сообщение Alek Lem »

Коты, всем привет и доброго времени суток!Вопрос про команду lpm. Тут, на радиокоте, написан такой кусочек кода:

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

ReadArray:
          ldi ZH,High(MyArray*2) ;загрузка адреса 0-го
          ldi ZL,Low(MyArray*2)  ;элемента в рег. пару Z

          ldi Temp1,0
          add ZL,Temp          ;прибавление
          adc ZH,Temp1         ;внутр. адреса

          lpm                  ;загрузка из ПЗУ

          mov Temp1,R0         ;копирование
          out PortB,Temp1      ;вывод в порт
          inc Temp             ;увелич. внутр. адреса
          rjmp ReadArray       ;в начало цикла

MyArray:
.db 12,16,3,4,10,17,255,37,158,14,13,98
.db 14,85,30,9,145,52,64,49,119,72,209,46
Далее, идёт пояснение:
Что значит "*2"? Дело в том, что каждая команда содержит два байта информации и занимает, таким образом, две ячейки ПЗУ. Поэтому, счетчик команд считает 2 адреса как один. Метка содержит именно данные для счетчика команд. Чтобы получить реальный адрес ПЗУ, необходимо увеличить адрес метки в 2 раза. Что мы и делаем.
Вот отрывок из книги Ревича:

Изображение

Стало интересно. Выходит, что кроме счетчика команд, который считает слова в памяти программ, есть еще какой-то счетчик, который отсчитывает байты Flash-памяти? Иначе, зачем указывать адреса байт -- кто их будет читать?
Реклама
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Сообщение dgrett »

Читать будет команда LPM
Я всё-всё узнAю и стану профессором.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Alek Lem писал(а):Выходит, что кроме счетчика команд, который считает слова в памяти программ, есть еще какой-то счетчик, который отсчитывает байты Flash-памяти? Иначе, зачем указывать адреса байт -- кто их будет читать?
Назначение счетчика команд - указатель на выполняемую команду, адресуется в словах (16бит). Команда LPM считывает один байт в R0 из флеш по адресу лежащему в Z (адрес побайтный). Метки в ассемблере для AVR адресуются пословно, поэтому в Z заносится двойное значение метки.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Дополнительный побайтный счетчик организован программно. Попробуйте, к примеру, сделать таблицу с нечетным числом байт и увидите, что будет вызов 0-байта
Спойлер

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

.INCLUDE "m8515def.inc"
.def	Temp=R20
.def	Temp1=R21

	CLR	Temp
	ldi Temp1,0

ReadArray:
          ldi ZH,High(MyArray*2) ;???????? ?????? 0-??
          ldi ZL,Low(MyArray*2)  ;???????? ? ???. ???? Z

;          ldi Temp1,0
          add ZL,Temp          ;???????????
          adc ZH,Temp1         ;?????. ??????

          lpm                  ;???????? ?? ???

          out PortB,r0      ;????? ? ????
;         mov Temp1,R0         ;???????????
;          out PortB,Temp1      ;????? ? ????
          inc Temp             ;??????. ?????. ??????
          rjmp ReadArray       ;? ?????? ?????
.org	0x40
MyArray:
.db 12,16,3;,4,10,17,255,37,158,14,13,98
.db 14,85,30,9,145,52,64,49,119,72,209,46
MyArray_END:
.EXIT
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 526
Зарегистрирован: Вс дек 28, 2014 18:35:34
Откуда: Луганск

Сообщение Alek Lem »

dgrett писал(а):Читать будет команда LPM
Команда не умеет читать. Читать может устройство.
Z_h_e писал(а):
Alek Lem писал(а):Выходит, что кроме счетчика команд, который считает слова в памяти программ, есть еще какой-то счетчик, который отсчитывает байты Flash-памяти? Иначе, зачем указывать адреса байт -- кто их будет читать?
Назначение счетчика команд - указатель на выполняемую команду, адресуется в словах (16бит). Команда LPM считывает один байт в R0 из флеш по адресу лежащему в Z (адрес побайтный). Метки в ассемблере для AVR адресуются пословно, поэтому в Z заносится двойное значение метки.
Спасибо, хорошее объяснение, но чуток не на мой вопрос. Я спрашивал, как именно происходит отсчет адреса в ROM побайтно командой plm ? Ведь адрес ROM умеет отсчитывать, на сколько я знаю, только счетчик команд (регистр адреса). А он это делает пословно. Тогда какому устройству предназначен побайтный адрес ? Возможно, что компилятор, видя команду plm, переводит побайтный адрес из регистра Z обратно в пословный для счетчика команд ?

akl, вроде бы, у Ревича на этот счет написано немного другое:

Изображение
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Alek Lem писал(а):Возможно, что компилятор, видя команду plm, переводит побайтный адрес из регистра Z обратно в пословный для счетчика команд ?
Вот опкод команды LPM 1001 0101 1100 1000, не во что другое компилятор его не переведет, и не добавит команд правящих Z. Если бы компилятор додумывлася править Z, то было бы :facepalm: и это уж никак не был бы ассемблер. Каким образом работает команда , забота декодера команд. Осмелюсь предположить что по команде LPM камень выставляет на шину адреса половину Z, считывается все слово, но в регистр-получатель загружает младшую или старшую часть слова, в зависимости от младшего бита в Z. Но это вопросы архитектуры камня, известные лишь разрабам и программиста в принципе волновать не должно.

Добавлено after 4 minutes 52 seconds:
Alek Lem писал(а):Ведь адрес ROM умеет отсчитывать, на сколько я знаю, только счетчик команд (регистр адреса).
Счетчик команд ничего не считывает, он хранит адрес для выборки команд.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Сообщение dgrett »

LPM немного мне напоминает Зайлоговский LDIR, только очень упрощённый.
Я всё-всё узнAю и стану профессором.
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Alek Lem писал(а):...
Это как раз и имелось ввиду, т.к. ещё не встречал архитектуры с порядком следования байт отличным от формата младший-старший. Например, код команды LPM Load Program Memory 0x95C8 в листинге видится как 0xC895.
СпойлерИзображение
LPM.png
(18.91 КБ) 656 скачиваний
Директива .DB позволяет нарушить этот формат, в отличие от директивы .DW Можете попробовать.
Вымогатель припоя
Аватара пользователя
Сообщения: 526
Зарегистрирован: Вс дек 28, 2014 18:35:34
Откуда: Луганск

Сообщение Alek Lem »

akl, спасибо.
Z_h_e писал(а):
Alek Lem писал(а):Ведь адрес ROM умеет отсчитывать, на сколько я знаю, только счетчик команд (регистр адреса).
Счетчик команд ничего не считывает, он хранит адрес для выборки команд.
Я и не писал, что он что-то считывает...Он считает -- поэтому и "счетчик" :-)
Z_h_e писал(а):Но это вопросы архитектуры камня, известные лишь разрабам и программиста в принципе волновать не должно.
Ок, не буду морочить голову. Теперь вопрос более прикладной. Командой .db заносится массив чисел, который в процессе работы программы, выгружается, например, в порты. Но с тем же успехом, я мог бы занести этот массив в ячейки ОЗУ (которые идут после адресов РОН и РВВ) и считывать массив оттуда.
Последний раз редактировалось Alek Lem Сб апр 15, 2017 14:53:46, всего редактировалось 1 раз.
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Зачем ОЗУ, предначенном для врЕменного хранения данных использовать для хранения констант.
Вымогатель припоя
Аватара пользователя
Сообщения: 526
Зарегистрирован: Вс дек 28, 2014 18:35:34
Откуда: Луганск

Сообщение Alek Lem »

Ясно, для экономии ОЗУ и единообразия логики работы с данными. Просто я сперва решил, что косвенная адресация -- это необходимость, а оказалось, что для удобства.
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Из ОЗУ выборка быстрее
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Да, быстрее, но всю скорость съест загрузка.
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Так и остальное надо оптимизировать.
Копейка - рубль бережет.
Друг Кота
Аватара пользователя
Сообщения: 15789
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Если речь о неизменных константах - предпочтение ПЗУ, если в процессе работы программы данные изменяются - предпочтение массиву в ОЗУ. При том, что в некоторых ситуациях размещение будет равноценным (просто прийдется использовать иные наборы команд для доступа и использования данных).
8)
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Здесь я полностью согласен, если не критично время выполнения.
Модератор
Аватара пользователя
Сообщения: 19100
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

Alek Lem писал(а):Я спрашивал, как именно происходит отсчет адреса в ROM побайтно командой plm ? Ведь адрес ROM умеет отсчитывать, на сколько я знаю, только счетчик команд (регистр адреса).
не надо путать счетчик команд и указатель адреса (в данном случае регистровую пару Z).
указатель адреса адресует побайтно.
тем более, что есть команды длиной больше 1 слова. поэтому счетчик команд считает команды, а не слова.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Starichok51 писал(а):тем более, что есть команды длиной больше 1 слова. поэтому счетчик команд считает команды, а не слова.
Я не соглашусь с такой формулировкой. Организация памяти программ в AVR n*16. Я не видел подробной схемы организации памяти и шин AVR, но все указывает на то (по моему разумению) что шина данных для памяти программ 16 битная, возможность (физическая) чтения данных побайтно отсутствует. Считайте что ячейки памяти 16 битные. Записи побайтной тоже нет.

Т.е. счетчик команд адресует именно слова (а не считает команды) и не потому что нет команд однобайтных, а потому что ячейки памяти 16 битные. Изменение счетчика команд производит декодер команд.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Модератор
Аватара пользователя
Сообщения: 19100
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

Z_h_e писал(а):возможность (физическая) чтения данных побайтно отсутствует.
присутствует.
меня не волнует, как команда lpm выбирает всего один байт из программной памяти. скорее всего, точно также, как из ОЗУ - побайтно, а не из слова.
а что нет записи в программную память - это всем известно.

да, счетчик команд выбирает слова. но сколько слов он выберет, зависит от длины команды. именно поэтому он считает КОМАНДЫ, а не слова.
и в отладчике ты НИКОГДА не сможешь сделать точку останова внутри двухсловной команды.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Starichok51 писал(а):присутствует.
меня не волнует, как команда lpm выбирает всего один байт из программной памяти. скорее всего, точно также, как из ОЗУ - побайтно, а не из слова.
То что программиста не должен волновать этот вопрос, я обозначал. В ДШ указано что организация памяти программ 16 битная. Равно как при 8ми битной организации, не читает ядро ниблами, так и тут не читает байтами. Кроме того, не кажется странным, что МК выбирает 16битную команду за один такт, а один байт данных читает аж за три? Точно также биториентированные команды не работают с битами по факту. Выборка байта из СОЗУ и модификация бита, запись байта обратно или Вы думаете для каждого бита есть свой адрес ? Это ж какая шина адреса должна быть?
Starichok51 писал(а):да, счетчик команд выбирает слова. но сколько слов он выберет, зависит от длины команды. именно поэтому он считает КОМАНДЫ, а не слова.
Счетчик ничего не выбирает, это всего-лишь указаетель. Этим занимается декодер команд и значение программного счетчика тоже меняет декодер команд, в зависимости от команды и ее результата.
Starichok51 писал(а):отладчике ты НИКОГДА не сможешь сделать точку останова внутри двухсловной команды
Конечно нельзя, первый раз вижу что такое можно даже обсуджать.
Starichok51 писал(а):а что нет записи в программную память - это всем известно.
Есть, но только по словно, опять же из-за 16 битной организации флеш, перед этим стирая страницы.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Ответить

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