реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Как сделать IJMP внутри программы на Си?
hakimulla
сообщение Mar 28 2012, 18:50
Сообщение #1





Группа: Новичок
Сообщений: 2
Регистрация: 4-01-11
Пользователь №: 62 006



Объясните, пожалуйста, как оформить индексный переход IJMP в программе
на Си.
Можно ли как-нибудь прочитать значение Program Counter (PC) для
AT90USB162?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Mar 28 2012, 19:27
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(hakimulla @ Mar 28 2012, 21:50) *
Объясните, пожалуйста, как оформить индексный переход IJMP в программе
на Си.

Зачем именно IJMP?

Цитата(hakimulla @ Mar 28 2012, 21:50) *
Можно ли как-нибудь прочитать значение Program Counter (PC) для
AT90USB162?

Напрямую - нет. И зачем он?
Ненапрямую можно так:
Код
unsigned short GetPC()
{
    unsigned char *ptr=(unsigned char *)SP;
    ptr+=2;
    unsigned short result=*ptr--;
    result+=(*ptr)<<8;
    
    return result;
}
Go to the top of the page
 
+Quote Post
hd44780
сообщение Mar 29 2012, 05:49
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Цитата(hakimulla @ Mar 28 2012, 21:50) *
Объясните, пожалуйста, как оформить индексный переход IJMP в программе
на Си.
Можно ли как-нибудь прочитать значение Program Counter (PC) для
AT90USB162?


А зачем вообще это в программе на Си?
Хотите применять ассемблерные переходы и сопутствующую хрень (типа значения PC) - пишите на асме.
В Си об этом компилятор думает. Это одна из его задач.

Сообщение отредактировал hd44780 - Mar 29 2012, 05:50


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
-SANYCH-
сообщение Mar 29 2012, 06:19
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 289
Регистрация: 6-12-05
Пользователь №: 11 864



На языке С джампы можно сделать с помощью "goto". Хотя это не есть хорошо.
Go to the top of the page
 
+Quote Post
hakimulla
сообщение Mar 29 2012, 06:26
Сообщение #5





Группа: Новичок
Сообщений: 2
Регистрация: 4-01-11
Пользователь №: 62 006



Цитата(_Артём_ @ Mar 28 2012, 22:27) *
Зачем именно IJMP?
Напрямую - нет. И зачем он?

Спасибо за подсказку, но можно ли это сделать без хитростей со стеком?
Мне нужно поднять производительность. Оптимизирую код ассемблерными
вставками. Прога большая - поэтому она на СИ.
Для выполнения команды IJMP в регистр Z нужно загружать адреса
меток, но как их получить в ассемблерной вставке? На момент компиляции
и линковки эти адреса меток известны. Вопрос в синтаксисе. Как их
задать и как к ним обратиться внутри ассемблерной вставки?


Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 29 2012, 07:06
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (hakimulla @ Mar 29 2012, 09:26) *
Для выполнения команды IJMP в регистр Z нужно загружать адреса
меток, но как их получить в ассемблерной вставке?
Какой компилятор-то хоть? В памяти отложилось, что GCC позволяет брать адреса от меток. Универсального средства нет - не Сишное это дело. Возможно стоить подумать и переписать полностью на асме отдельные узкие функции, а не мешать компилятору отдельными вставками?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Mar 29 2012, 09:20
Сообщение #7


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(hakimulla @ Mar 29 2012, 05:26) *
Для выполнения команды IJMP в регистр Z нужно загружать адреса
меток, но как их получить в ассемблерной вставке?

Попробуйте вот так
asm volatile ("ldi r30,lo8(pm(desiredLabel))");
asm volatile ("ldi r31,hi8(pm(desiredLabel))");


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Alex11
сообщение Mar 29 2012, 15:23
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 106
Регистрация: 23-10-04
Из: С-Петербург
Пользователь №: 965



Или поставьте параллельно ассемблерные метки: asm("AsmLabel1:"); и потом обращайтесь к ним.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Mar 29 2012, 16:54
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Вообще конечно это муть полная. Оптимизировать нужно алгоритм программы глобально а не "вылизывать код" в каком то одном месте. Но это сугубо мое мнение. Простите за оффтоп.


--------------------
Go to the top of the page
 
+Quote Post
ReAl
сообщение Mar 29 2012, 18:49
Сообщение #10


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Сергей Борщ @ Mar 29 2012, 10:06) *
В памяти отложилось, что GCC позволяет брать адреса от меток.

Есть такое
http://electronix.ru/forum/index.php?showtopic=61802&hl=
http://electronix.ru/forum/index.php?showt...mp;#entry520130


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Apr 3 2012, 02:59
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



В стандартной библиотеке Си есть файл setjmp.h, объявляющий макросы и тип данных для нелокальных переходов. Посмотри, может тебе это подойдет.
Go to the top of the page
 
+Quote Post
Navovvol
сообщение Apr 3 2012, 13:00
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 105
Регистрация: 9-09-11
Пользователь №: 67 080



нужно просто избавиться от злого _delay_ms(...); wink.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Apr 5 2012, 13:40
Сообщение #13


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Navovvol @ Apr 3 2012, 16:00) *
нужно просто избавиться от злого _delay_ms(...); wink.gif


Или использовать Protothreads
Или РТОСь
Go to the top of the page
 
+Quote Post
Д_М
сообщение Aug 8 2012, 19:22
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 15-04-05
Из: Краснодар
Пользователь №: 4 185



Не надо использовать 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])();
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Aug 9 2012, 06:18
Сообщение #15


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(hakimulla @ Mar 29 2012, 10:26) *
...в регистр Z нужно загружать адреса
меток, но как их получить в ассемблерной вставке?...эти адреса меток известны. Вопрос в синтаксисе. Как их
задать и как к ним обратиться внутри ассемблерной вставки?


я поддерживаю мысли тут высказанные:
1) гоу-ту на сях это зло. можно писать без него.
2) оптимизировать надо общий алгоритм а не портить жизнь оптимизатору(кстати он то включён правильно, с максимальным приоритетом по скорости выполнения???)
3) но если хочется на азме...

на азме это всего три команды. чтоб экономить и не брать каждый раз адрес - можно прибавлять только оффсеты к конкретному базовому адресу(хотя и его можно захардкодить или вычислить заранее).

Пример(рыба):

CODE
.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
оффсеты и базовый адрес на рантайме не обязательно складывать. можно эту требуху хранить и в памяти, в таблице (к примеру).

Сообщение отредактировал IgorKossak - Aug 9 2012, 09:27
Причина редактирования: [codebox] для длинного кода
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th June 2025 - 11:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.02201 секунд с 7
ELECTRONIX ©2004-2016