hakimulla 0 28 марта, 2012 Опубликовано 28 марта, 2012 · Жалоба Объясните, пожалуйста, как оформить индексный переход IJMP в программе на Си. Можно ли как-нибудь прочитать значение Program Counter (PC) для AT90USB162? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 28 марта, 2012 Опубликовано 28 марта, 2012 · Жалоба Объясните, пожалуйста, как оформить индексный переход IJMP в программе на Си. Зачем именно IJMP? Можно ли как-нибудь прочитать значение Program Counter (PC) для AT90USB162? Напрямую - нет. И зачем он? Ненапрямую можно так: unsigned short GetPC() { unsigned char *ptr=(unsigned char *)SP; ptr+=2; unsigned short result=*ptr--; result+=(*ptr)<<8; return result; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 29 марта, 2012 Опубликовано 29 марта, 2012 (изменено) · Жалоба Объясните, пожалуйста, как оформить индексный переход IJMP в программе на Си. Можно ли как-нибудь прочитать значение Program Counter (PC) для AT90USB162? А зачем вообще это в программе на Си? Хотите применять ассемблерные переходы и сопутствующую хрень (типа значения PC) - пишите на асме. В Си об этом компилятор думает. Это одна из его задач. Изменено 29 марта, 2012 пользователем hd44780 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
*ZEVS* 0 29 марта, 2012 Опубликовано 29 марта, 2012 · Жалоба На языке С джампы можно сделать с помощью "goto". Хотя это не есть хорошо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hakimulla 0 29 марта, 2012 Опубликовано 29 марта, 2012 · Жалоба Зачем именно IJMP? Напрямую - нет. И зачем он? Спасибо за подсказку, но можно ли это сделать без хитростей со стеком? Мне нужно поднять производительность. Оптимизирую код ассемблерными вставками. Прога большая - поэтому она на СИ. Для выполнения команды IJMP в регистр Z нужно загружать адреса меток, но как их получить в ассемблерной вставке? На момент компиляции и линковки эти адреса меток известны. Вопрос в синтаксисе. Как их задать и как к ним обратиться внутри ассемблерной вставки? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 116 29 марта, 2012 Опубликовано 29 марта, 2012 · Жалоба Для выполнения команды IJMP в регистр Z нужно загружать адреса меток, но как их получить в ассемблерной вставке? Какой компилятор-то хоть? В памяти отложилось, что GCC позволяет брать адреса от меток. Универсального средства нет - не Сишное это дело. Возможно стоить подумать и переписать полностью на асме отдельные узкие функции, а не мешать компилятору отдельными вставками? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 29 марта, 2012 Опубликовано 29 марта, 2012 · Жалоба Для выполнения команды IJMP в регистр Z нужно загружать адреса меток, но как их получить в ассемблерной вставке? Попробуйте вот так asm volatile ("ldi r30,lo8(pm(desiredLabel))"); asm volatile ("ldi r31,hi8(pm(desiredLabel))"); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex11 3 29 марта, 2012 Опубликовано 29 марта, 2012 · Жалоба Или поставьте параллельно ассемблерные метки: asm("AsmLabel1:"); и потом обращайтесь к ним. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prottoss 0 29 марта, 2012 Опубликовано 29 марта, 2012 · Жалоба Вообще конечно это муть полная. Оптимизировать нужно алгоритм программы глобально а не "вылизывать код" в каком то одном месте. Но это сугубо мое мнение. Простите за оффтоп. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 29 марта, 2012 Опубликовано 29 марта, 2012 · Жалоба В памяти отложилось, что GCC позволяет брать адреса от меток. Есть такое http://electronix.ru/forum/index.php?showtopic=61802&hl= http://electronix.ru/forum/index.php?showt...mp;#entry520130 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexeyv 0 3 апреля, 2012 Опубликовано 3 апреля, 2012 · Жалоба В стандартной библиотеке Си есть файл setjmp.h, объявляющий макросы и тип данных для нелокальных переходов. Посмотри, может тебе это подойдет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
navovvol 0 3 апреля, 2012 Опубликовано 3 апреля, 2012 · Жалоба нужно просто избавиться от злого _delay_ms(...); ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 5 апреля, 2012 Опубликовано 5 апреля, 2012 · Жалоба нужно просто избавиться от злого _delay_ms(...); ;) Или использовать Protothreads Или РТОСь Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Д_М 0 8 августа, 2012 Опубликовано 8 августа, 2012 · Жалоба Не надо использовать IJMP, так как это грубо и вульгарно, особенно с точки зрения программирования на С. Используйте ICALL void (*ptr)(void);//объявление пременной типа указатель на фунцию типа void (*ptr)();//вызов функции типа void косвенно, через адрес в перенной А лучше оформить массив с адресами функций __flash void (*hnd_I2C_steps [])(void) = {I2C_step_0, I2C_step_1, I2C_step_2, I2C_step_3, I2C_step_4, I2C_step_5}; (*hnd_I2C_steps [i2C_step])(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 9 августа, 2012 Опубликовано 9 августа, 2012 (изменено) · Жалоба ...в регистр Z нужно загружать адреса меток, но как их получить в ассемблерной вставке?...эти адреса меток известны. Вопрос в синтаксисе. Как их задать и как к ним обратиться внутри ассемблерной вставки? я поддерживаю мысли тут высказанные: 1) гоу-ту на сях это зло. можно писать без него. 2) оптимизировать надо общий алгоритм а не портить жизнь оптимизатору(кстати он то включён правильно, с максимальным приоритетом по скорости выполнения???) 3) но если хочется на азме... на азме это всего три команды. чтоб экономить и не брать каждый раз адрес - можно прибавлять только оффсеты к конкретному базовому адресу(хотя и его можно захардкодить или вычислить заранее). Пример(рыба): .equ OFFSET_TO_SUBROUTINE_1 = (Subroutine_1 - PointGetTempAddres) .equ OFFSET_TO_SUBROUTINE_2 = (Subroutine_2 - PointGetTempAddres) rcall PointGetTempAddres PointGetTempAddres: pop YH pop YL ;-- YH:YL = address in FLASH "PointGetTempAddres" movw ZL,YL adiw ZL,OFFSET_TO_SUBROUTINE_2 ;-- call Subroutine_2 icall movw ZL,YL adiw ZL,OFFSET_TO_SUBROUTINE_1 ;-- call Subroutine_1 icall ;-- stop Halt: rjmp Halt Subroutine_1: ldi r16,100 ret Subroutine_2: ldi r16,200 ret прау слов: этому подходу - в обед сто лет. впервые приенялся в вирусной технологии на заре досика... если адреса подпрограмм дальше чем 64 байта, то команды adiw надо заменить на пару add,adc оффсеты и базовый адрес на рантайме не обязательно складывать. можно эту требуху хранить и в памяти, в таблице (к примеру). Изменено 9 августа, 2012 пользователем IgorKossak [codebox] для длинного кода Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться