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

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

как известно под названием массива скрывается адрес его нулевого элемента

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

MyArray:
.db 12,16,3,4,10,17,255,37,158,14,13,98
и если бы было написано вот так

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

ldi ZH,High(MyArray) ;загрузка адреса 0-го
ldi ZL,Low(MyArray)  ;элемента в рег. пару Z
то это бы не вызвало никаких недоумений
но там записано вот так

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

ldi ZH,High(MyArray*2) ;загрузка адреса 0-го
ldi ZL,Low(MyArray*2)  ;элемента в рег. пару Z
кто может разжевать зачем там идет умножение на 2 ?
Tell Me The Truth
Реклама
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Разуй глаза, в том отрывке который ты дал - там написано объяснение почему так. Неужели не видишь?
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

Alexeyslav, да вижу я все
то обяснение для меня ничего не обясняет
Tell Me The Truth
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Свежий, через Z (во флэше) адресуются команды длиной 2 байта, константы имеют длину 1 байт. Для того и умножают.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Да уж объяснил так еще больше запутал.

На самом деле, метки - это числовые адреса команд. Поскольку, к памяти обращаемся мы побайтно, а адрес метки дан для 16-битной организации адресного пространства, то адрес-метку нужно умножать на два.
Причем, <метка>*2 адресует один байт, а <метка>*2+1 адресует следующий байт. Поэтому у вас в примере ошибка - старшая и младшая часть слова у вас будут равны одному и тому же байту из памяти.
Контактная информация:
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

FreshMan, для AVR метки во флэш-памяти представляют собой адрес в машинных словах. А машинное слово у 8-битных AVR-ок равно, как ни странно, 16 битам, т.е. 2-м байтам. Доступ к памяти с помощью команд LPM/SPM производится с точностью до байта.

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

Адрес в машинных словах (по 16 бит)
  0       1       2       3       4       5       6       7       8       9
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--
  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
Адрес в байтах
Допустим метка DAT имеет значение 7 и надо достать оттуда один байт. Так как машинное слово равно двум байтам, то 7*2=14. Вот и надо достать байт по адресу 14.
Чтобы быть ещё более точным, то адресация в словах работает только в сегменте кода (.cseg). В сегменте данных (.dseg) и EEPROM (.eseg) адреса в байтах.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

Kavka писал(а):А машинное слово у 8-битных AVR-ок равно, как ни странно, 16 битам, т.е. 2-м байтам.
а шо может быть и по другому ?
слово может иметь другой размер ?
Tell Me The Truth
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Разумеется. Машинное слово бывает от 5 (если не ошибаюсь) до 128 бит и зависит исключительно от архитектуры АЛУ.
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Как ни странно, и байт и слово может иметь другой размер.
Название «байт» (слово byte представляет собой сокращение словосочетания BinarY TErm — «двоичный терм») было впервые использовано в 1956 году В. Бухгольцем (англ. Werner Buchholz) при проектировании первого суперкомпьютера IBM 7030 (англ.) для пучка одновременно передаваемых в устройствах ввода-вывода шести битов. Позже, в рамках того же проекта, байт был расширен до восьми бит.

Ряд ЭВМ 1950-х и 1960-х годов (БЭСМ-6, М-220) использовали 6-битовые символы в 48-битовых или 60-битовых машинных словах. В некоторых моделях ЭВМ производства Burroughs Computer Corporation (англ.) (ныне Unisys) размер символа был равен 9 битам. В советской ЭВМ Минск-32 использовался 7-битный байт. Постепенно 8-битные байты стали стандартом де-факто; с начала 1970-х в большинстве компьютеров байты состоят из 8 бит, а размер машинного слова кратен 8 битам.
(с) Википедия
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Alexeyslav, да, оно конечно так, но сегодня понятие "байт" устоялось в значении "группа из 8-ми бит". :)

FreshMan, например у архитектуры ARM, в оригинальном наборе инструкций, 32-битное машинное слово. Позже у ARM появился режим Thumb, в котором машинное слово 16-битное.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

FreshMan писал(а):а шо может быть и по другому ?
У 8051 слово команды длиной 1, 2 и 3 байта.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Gudd-Head, 8051 это CISC. И к нему термин "машинное слово" применимо с оговорками. Там, скорее, "длинна команды".
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Всё, FreshMan в ауте.
Docendo discimus
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

pyzhman, не угадали....., я просто готовлю каверзные вопросы :))
кстати, команда lmp работает только с регистрами Z и R0 ?
по другому никак ?
Tell Me The Truth
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

FreshMan писал(а):lmp работает только с регистрами Z и R0 ?
LMP? :shock: Может, LPM? :)))
Есть ещё LPM Rd, Z(+).
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

Gudd-Head писал(а):LMP? Может, LPM?
о....., да сори :)) ......, подумаешь ..., мальца ошибся :))
в данной статье http://radiokot.ru/start/mcu_fpga/avr/12/

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

;****************************************************
; ОБРАБОТЧИК ПРЕРЫВАНИЯ КОМПАРАТОРА
;****************************************************

Timer1_comp1:


         ldi Temp,0            ;обнуление таймера
         out TCNT1H,Temp
         out TCNT1L,Temp


         cpi Temp1,30          ;сравнить с крайним знач.
         breq Init             ;если равно - загрузка нач. знач.


ReadArray:
         ldi ZH,High(Array*2)  ;загрузка начального адреса массива
         ldi ZL,Low(Array*2)

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

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

         mov Temp,R0           ;копирование в РОН
         inc Temp1             ;увеличение внутр. адреса

         rjmp Output           ;перейти на вывод в порт

Init:    ldi Temp1,0          ;загрузить нач. значение
         rjmp ReadArray

Output:  out PortB,Temp       ;вывод в порт

         reti                  ;выход из обработчика


Array:

.db   0b10000001,0b01000010
.db   0b00100100,0b00011000
.db   0b00011000,0b00111100
.db   0b01111110,0b11111111
.db   0b11100111,0b11000011
.db   0b10000001,0b11000001
.db   0b11100001,0b11110001
.db   0b11111001,0b11111101
.db   0b11111111,0b01111111
.db   0b00111111,0b00011111
.db   0b00001111,0b00000111
.db   0b00000011,0b00000001
.db   0b00000011,0b00000101
.db   0b00001001,0b00010001
.db   0b00100001,0b01000001
для меня непонятны следующие строки

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

ldi Temp,0            ;прибавление внутр. адреса
 add ZL,Temp1
 adc ZH,Temp
почему делается именно так , а не скажем вот так ?

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

ldi Temp,0            ;прибавление внутр. адреса
 adс ZL,Temp1
 add ZH,Temp
Tell Me The Truth
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

FreshMan писал(а): для меня непонятны следующие строки

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

ldi Temp,0            ;прибавление внутр. адреса
 add ZL,Temp1
 adc ZH,Temp
почему делается именно так , а не скажем вот так ?

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

ldi Temp,0            ;прибавление внутр. адреса
 adс ZL,Temp1
 add ZH,Temp
команда ADC прибавляет флаг переноса, т.е. "1", если с младшими случается переполнение, поэтому к старшему нужно прибавить "0" именно командой ADC, а если прибавим командой ADD, то в случае переполнения младших старшему ничего не перепадет.

p.s. Если применять ADC к младшему байту, то к нему может прибавиться результат предыдущей любой операции влияющей на флаг переноса.... Во загнул как :hunger:
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

FreshMan писал(а):мальца ошибся
После такого мальца спутники мимо Венеры пролетают. :))
FreshMan, когда паять и программировать вживую начнем? А то такое ощущение, что голой теорией занимаетесь.
Docendo discimus
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

zero648 писал(а):команда ADC прибавляет флаг переноса, т.е. "1", если с младшими случается переполнение
а что будет когда со старшим случится переполнение ?
pyzhman писал(а): А то такое ощущение, что голой теорией занимаетесь.
неа....., счас я занимаюсь голым ремонтом :)) ,а в передишках штудирую асм для разминки мозгов :))
похожие мигалки я уже паял и програмировал на Си, а тут стало интерестно как же вся эта кухня работает на асме :tea:
Tell Me The Truth
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

FreshMan писал(а):команда ADC прибавляет флаг переноса, т.е. "1", если с предыдущим случается переполнение
Так правильнее.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Ответить

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