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

Обсуждаем контроллеры компании Atmel.
Ответить
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 39
Зарегистрирован: Пн дек 31, 2012 13:16:59

Сообщение *скрыто* »

Вот тут еще вопрос возник при изучении чужой программы, что это такое +'0' ?
Сам нашел только то, что компилятор поддерживает операторы и в данном случае -1 переводит в 0xff, а что такое -1 + '0'? Или таким образом автор имел ввиду что при начале цикла счетчик установился с 255 в 0?

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

  
            ldi     r20, -1 + '0'
_bcd1:  inc     r20
            subi    r16, low(10000)         ;-10000
            sbci    r17, high(10000)
            brcc    _bcd1

            ldi     r19, 10 + '0'
_bcd2:  dec     r19
           subi    r16, low(-1000)         ;+1000
           sbci    r17, high(-1000)
           brcs    _bcd2
Реклама
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

'0' (в апострофах) скорее всего интерпретируется как символ, т.е. будет 10 + код символа 0 (30h или 48 в десятичной)
Реклама
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 39
Зарегистрирован: Пн дек 31, 2012 13:16:59

Сообщение *скрыто* »

Аа, точно. вроде как подпрограмма называется bin16_ascii:
добавляют bcd+48=ascii ?
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Ну да, посмотрите таблицу.
Реклама
Эиком - электронные компоненты и радиодетали
Мучитель микросхем
Аватара пользователя
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

Сообщение unalex »

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

ascii2num:
				; num = ascii - 0x30;
				subi r24, 48
				ret

num2ascii:
				; ascii = num -(-0x30) = num + 0x30
				subi r24, -48
				ret
а это не то же самое?

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

ldi     r20, 0x2F
_bcd1:  inc     r20
            subi    r16, 0x10
            sbci    r17, 0x27
            brcc    _bcd1

            ldi     r19, 0x3A
_bcd2:  dec     r19
           subi    r16, 0x17
           sbci    r17, 0xFC
           brcs    _bcd2
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Реклама
Родился
Сообщения: 2
Зарегистрирован: Вс фев 17, 2013 16:30:45

Сообщение ahtyng »

Добрый день, так сложилось, что в руках у меня плата stm32f4decovery в МК я профон и погуглив понял, что изучать МК лучше начинать с ассемблера, но тут столкнулся с проблемой такого характера: никто не пишет под stm32 на ассемблере единственное что нашел это пара примеров для keil, но там ассемблер отличатся от интеловского. Вообщем посоветуйте чего делать, перейти на атмел, забить на ассемблер и начать грызти С++ или остановиться на keil?
Реклама
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Начиная с С на STM32, просто масштаб не тот чтобы под этот камень начинать с ассемблера.
Вот под AVR - можно и с ассемблера.
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Тут ещё проблема в том, что архитектура гораздо сложнее, и без опыта лучше не браться за ассемблер. Если AVR просто как валенок, соответственно и его ассемблер, то с STM32 такое не прокатит.

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

Сообщение afz »

ploop писал(а):Тут ещё проблема в том, что архитектура гораздо сложнее, и без опыта лучше не браться за ассемблер. Если AVR просто как валенок, соответственно и его ассемблер, то с STM32 такое не прокатит.

Хотя бы какие-то части вынести в качестве ассемблерной вставки ещё можно, но делать полностью проект нет смысла. Там на одном конфигурировании мозг взорвётся.
Я бы не сказал. Что касается конфигурирования, то нет особой разницы, на Си его клепать, или на асме, по-любому надо в какой-то набор портов распихать какое-то количество констант, то есть на каждый шаг инициализации либо одна строчка на Си, либо две на асме, одна - загрузить константу в регистр, вторая - выдать ее в порт. Ну, и, опять же, простые действия, типа проверить битик в порту и перейти куда-то, если он взведен, на Си и на Асме занимают примерно одинаково. Зато Си - это дополнительный уровень абстракции. Если ты его заранее не знаешь (причем хорошо), да и еще камень незнакомый, результат вряд ли порадует.

А что действительно сложно на асме - это оптимизация по скорости для глубоко конвееризуемых процессоров, когда "инструкция z выполняется за один такт, но результат будет доступен через 17 тактов", вот тут действительно мозг взорвется, но ЦП большинства МК не такие... :))
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Кто хочет мозги размять? :)

Допустим, есть 8 байт (если важно — подряд, в ОЗУ или флэше), каждый содержит по 7 бит информации, 8-й бит — "ноль" (допустим, старший). Т.е. байты вида
01234567, где 1234567 — информационные биты.

Необходима компактная и/или быстрая функция, вставляющая "ноль" в N-ный бит N-ного байта.
Т.е. 8 байт принимаем, 8 байт выдаём. Первый байт идёт без изменения 01234567, ... четвёртый будет 12304567, ... , восьмой — 12345670.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

т.е. операцию INSERT с раздвиганием в сторону старшего разряда т.к. в ином случае произойдет потеря информации.
Кажется,мне что тут надо подготовить маску - для второй половины которая будет сдвигаться.
Затем копируем значение во временный регистр применяем маску и сдвигаем на одну позицию.
делаем операцию OR маски и результата, а затем XOR с временным регистром.

черт, нужный бит у нас будет в "1"... ну, обнулить его можно разными методами, лучше конечно во временном регистре эту 1 прописать сразу. Или как-то так...

Маску кстати можно перед циклом приравнять "$FF" и сдвигать её вправо заполняя нулем. Как только маска равна нулю - цикл закончен.
Контактная информация:
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Сообщение ILYAUL »

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

count=8
temp1=0xEF

XXX:
ld temp,X+
and temp,temp1
куда-то temp
sec
ror temp1
dec count
........
Проверь
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Alexeyslav , да. INSERT с раздвиганием. Двигать маску... Подумаю когда до бумажки доберусь) Потому что меня хватило только на разрезание регистра на две части, сдвиг одной и склеивание. Притом для каждого бита (байта) своя маска.
ILYAUL , вы просто вставляете нули.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

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

char mask[]={0b11111111,0b01111111,0b00111111,0b00011111,0b00001111,0b00000111,0b00000011,0b00000001,0b00000000};
char func(char x,char pos){
     char temp = x>>1;
     temp = temp & (mask[pos]>>1);
     x &= ~mask[pos];
     return x | temp;
}
На Сях будет как-то так. На ассемблер сейчас переводить лень, суть должна быть понятна и так.
Друг Кота
Аватара пользователя
Сообщения: 20093
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

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

Сообщение Kavka »

Gudd-Head писал(а):Необходима компактная и/или быстрая функция, вставляющая "ноль" в N-ный бит N-ного байта.
Что-то не уловил - перенос между 7-битными словами от младшего к старшему не нужен? Т.е. нужна вставка в один байт по указанным условиям?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

COKPOWEHEU писал(а):На Сях будет как-то так. На ассемблер сейчас переводить лень, суть должна быть понятна и так.
Идея та же. Чуть компактнее может быть. Нумерация битов так как в исходном сообщении Gudd-Head (хотя привычней наоборот).

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

unsigned char mask[]={0b11111111,0b01111111,0b00111111,0b00011111,0b00001111,0b00000111,0b00000011,0b00000001};
unsigned char insertzerobit(unsigned char x,unsigned char pos) {
    return ( ( (x & mask[pos]) >> 1 ) | (x & ~mask[pos]) );
}
Поправочка: Тут сдвиг в другую сторону, не в ту которую Gudd-Head указывал. Но смысл сохраняется.
:idea: Есть ещё идея как упростить.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Gudd-Head писал(а):Кто хочет мозги размять? :)
каждый содержит по 7 бит информации, 8-й бит — "ноль" (допустим, старший). Т.е. байты вида
01234567, где 1234567 — информационные биты.
На мой взгляд задача поставлена немного расплывчато. Поэтому вот мой вариант.
Если взять обычную нумерацию битов: 0-й - младший, 7-й - старший.
Т.е. байт будет вот так состоять из битов 76543210. И при вставке "0" биты сдвигаются в сторону старшего.
Тогда, хорошенько размяв мозги, раскатав их тонким слоем, чтобы на просвет можно было увидеть остатки математики в них застрявшие :)) можно сделать вот так.

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

unsigned char mask2[]={0b11111111,0b11111110,0b11111100,0b11111000,0b11110000,0b11100000,0b11000000,0b10000000};
unsigned char izb2(unsigned char x,unsigned char pos) {
    return ( x + (x & mask2[pos]) );
}
Компактней, как мне кажется, уже некуда.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

красивое решение
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

А компактная по какому критерию? По объему текста исходника, или коду? если по коду - то С отпадает(или нужно очень аккуратно использовать его) нужно делать на ассемблере. Одно только использование массива на С убивает эффективность и увеличивает размер кода.

И кстати почему-то никто не принимает во внимание что нужно обработать не ОДИН байт, а целых 8 байт за присест! В таком случае массив масок не нужен вовсе - маску можно формировать в рамках цикла по этим самым 8-ми байтам это всего один регистр и одна команда сдвига на итерацию. Какие при этом нужны массивы? да никаких!
Контактная информация:
Ответить

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