Перейти к содержанию
    

Как сделать IJMP внутри программы на Си?

Объясните, пожалуйста, как оформить индексный переход IJMP в программе

на Си.

Можно ли как-нибудь прочитать значение Program Counter (PC) для

AT90USB162?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Объясните, пожалуйста, как оформить индексный переход 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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Объясните, пожалуйста, как оформить индексный переход IJMP в программе

на Си.

Можно ли как-нибудь прочитать значение Program Counter (PC) для

AT90USB162?

 

А зачем вообще это в программе на Си?

Хотите применять ассемблерные переходы и сопутствующую хрень (типа значения PC) - пишите на асме.

В Си об этом компилятор думает. Это одна из его задач.

Изменено пользователем hd44780

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Напрямую - нет. И зачем он?

Спасибо за подсказку, но можно ли это сделать без хитростей со стеком?

Мне нужно поднять производительность. Оптимизирую код ассемблерными

вставками. Прога большая - поэтому она на СИ.

Для выполнения команды IJMP в регистр Z нужно загружать адреса

меток, но как их получить в ассемблерной вставке? На момент компиляции

и линковки эти адреса меток известны. Вопрос в синтаксисе. Как их

задать и как к ним обратиться внутри ассемблерной вставки?

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для выполнения команды IJMP в регистр Z нужно загружать адреса

меток, но как их получить в ассемблерной вставке?

Какой компилятор-то хоть? В памяти отложилось, что GCC позволяет брать адреса от меток. Универсального средства нет - не Сишное это дело. Возможно стоить подумать и переписать полностью на асме отдельные узкие функции, а не мешать компилятору отдельными вставками?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для выполнения команды IJMP в регистр Z нужно загружать адреса

меток, но как их получить в ассемблерной вставке?

Попробуйте вот так

asm volatile ("ldi r30,lo8(pm(desiredLabel))");

asm volatile ("ldi r31,hi8(pm(desiredLabel))");

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или поставьте параллельно ассемблерные метки: asm("AsmLabel1:"); и потом обращайтесь к ним.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В памяти отложилось, что GCC позволяет брать адреса от меток.

Есть такое

http://electronix.ru/forum/index.php?showtopic=61802&hl=

http://electronix.ru/forum/index.php?showt...mp;#entry520130

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В стандартной библиотеке Си есть файл setjmp.h, объявляющий макросы и тип данных для нелокальных переходов. Посмотри, может тебе это подойдет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нужно просто избавиться от злого _delay_ms(...); ;)

 

Или использовать Protothreads

Или РТОСь

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не надо использовать 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])();

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...в регистр 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

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

Изменено пользователем IgorKossak
[codebox] для длинного кода

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...