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

 
 
> Таблица переходов вместо Switch, Keil Си
AndreyS
сообщение Mar 23 2010, 15:28
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 235
Регистрация: 28-01-05
Из: Санкт-Петербург
Пользователь №: 2 276



Добрый день.

Если я не первый раз поднимаю эту тему, то заранее извиняюсь (я не смог придумать поисковику удобоваримое слово для поиска. На void* или таблица вываливается куча страниц).

Хочу заменить конструкцию Switch case на таблицу переходов и все это на языке Си.

Как вызвать процедуру по адресу я знаю, вопрос как бы мне заполнить таблицу с 256 значениями.
На асме я это реализовывал так:
Сначала создавал массив адресов на обработчик default, а затем в другом инклюднике прописывал (переопределял по вычисленным адресам определенные обработчики) Вот так:
Код
COM_SN_WRITE     EQU    42h                    ; Команда записи SN
    ORG TABEL_COM+(COM_SN_WRITE*2)              ; тут умножаю на 2, так как храню адрес из 2-х байт, в Keil Си он 3-х байтовый
    DW SEND_COM_SN_WRITE                               ; Ну а тут собственно сам обработчик (процедура). Тут ее адрес


SEND_COM_SN_WRITE:
       RET


TABEL_COM это адрес таблицы
COM_SN_WRITE номер команды
SEND_COM_SN_WRITE адрес обработчика

Как бы мне теперь так же сделать на Си в Keil?

PS Работу switch в Keil я разобрал, он работает с таблицей не так как мне нужно (она все равно перебором просматривает всю свою таблицу).


--------------------
Удачи.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aaarrr
сообщение Mar 23 2010, 15:43
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Определите массив указателей на функции, например, массив из 10 указателей на функции вида int func(int, int) будет выглядеть так:
Код
int (*zzz[10])(int, int);
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Mar 23 2010, 16:30
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Код
typedef void (*VECTORS)();

const VECTORS function[stQty] =
{
  f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,  f8,  f9,
  f10, f11, f12, f13, f14, f15, f16, f17, f18, f19,
  f20, f21, f22, f23, f24, f25, f26, f27, f28, f29,
  f30, f31, f32, f33, f34, f35, f36, f37, f38, f39,
  f40, f41, f42, f43, f44, f45, f46, f47, f48, f49,
  f50, f51, f52, f53, f54, f55, f56, f57, f58, f59,
  f60, f61, f62, f63, f64, f65, f66, f67, f68, f69,
  f70, f71, f72, f73, f74, f75, f76, f77, f78, f79,
  f80, f81, f82, f83, f84, f85, f86, f87, f88, f89,
  f90, f91, f92, f93, f94, f95, f96, f97, f98, f99,
  f100,f101,f102,f103
   };


Цитата(AndreyS @ Mar 23 2010, 19:28) *
...PS Работу switch в Keil я разобрал, он работает с таблицей не так как мне нужно (она все равно перебором просматривает всю свою таблицу).

Оптимизация включена?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
AndreyS
сообщение Mar 23 2010, 19:10
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 235
Регистрация: 28-01-05
Из: Санкт-Петербург
Пользователь №: 2 276



Цитата(Dog Pawlowa @ Mar 23 2010, 19:30) *
[code]typedef void (*VECTORS)();

const VECTORS function[stQty]={указатели}

Оптимизация включена?

спасибо большое за ответ. Меня интересовало как в таблицу, в произвольном порядке прописать адрес функции. Вот например таблица изначально заполнена адресом на один обработчик заглушку. Теперь я создал например обработчик 10-го позиционного номера таблицы. И хочу что бы компилятор в таблице заменил адрес 10 ячейки этой таблицы. На асме я это регулировал оргом, тут с _at_ такая штука не проходит. а нужно мне это для дополнения обработчиков. Ну всего 256 комбинаций (у меня байт проверяется), из них 200 определено. И вот хочу еще 2 определить, что бы не искать позицию в таблице, я хотел что бы компилятор (по моему указанию) высчитал позицию адреса в таблице и туда этот адрес положил. А как вызвать функию по адресу из этой таблицы я знаю, спасибо.

Цитата(Dog Pawlowa @ Mar 23 2010, 19:30) *
Оптимизация включена?

оптимхизация включена (какой уровень сейчас не скажу да это и не важно). У кейла в факе на сайте по этому поводу сказано что начиная 7 версии свитчь сам сворачивается в таблицу в зависимости отусловий (от кода). Я стал анализировать. Он таблицу создает сразу от 6 кейсов, если кейсы стоят последовательно (т.е. Сравниваемое значение в каждом кейсе отличается от предыдущего на 1). Если их перетасовать, то таблица появляетя уже если кейсов более 10. Но это все фигня. Я зашел в их функию ccall за которой в коде лежит таблица, и посмотрел что она делает. Оказалось что 3-х байтовая таблица это не просто адрес. А 2 байта адрес и значение кейса. И фукция производит в цикле поиск значенния первого байта адреса равного 0. Это означает для нее что вся таблица перебрана и совпадения нет. И тут находится адрес обработчика дефаулт значения. Если первый байт в таблице не равен 0, то тогда сравнивается 3-й байт в таблице (в нем лежит кейс значение). Если он совпал с входящим числом (switch), то выполняется переход на адрес (1 и 2 ячейки таблицы). Иначе ищет дальше. Нахрена такая таблица я не понял. Компактно - да, быстро - нет.


--------------------
Удачи.
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 4 2010, 23:56
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(AndreyS @ Mar 23 2010, 22:10) *
Теперь я создал например обработчик 10-го позиционного номера таблицы. И хочу что бы компилятор в таблице заменил адрес 10 ячейки этой таблицы. На асме я это регулировал оргом, тут с _at_ такая штука не проходит. а нужно мне это для дополнения обработчиков. Ну всего 256 комбинаций (у меня байт проверяется), из них 200 определено. И вот хочу еще 2 определить, что бы не искать позицию в таблице, я хотел что бы компилятор (по моему указанию) высчитал позицию адреса в таблице и туда этот адрес положил. А как вызвать функию по адресу из этой таблицы я знаю, спасибо.


А что мешает просто красиво задать массив, - с одной функцией в одной строке и коментарием в конце строки, который будет указывать номер текущей позиции:

Код
void CommonHandler()
{
}

void GetTimeHander()
{
  ...
}

void (*Handlers[])(void) =
{
    CommonHandler,      // 0
    CommonHandler,      // 1
    CommonHandler,      // 2
    CommonHandler,      // 3
    GetTimeHandler,     // 4
    CommonHandler,      // 5
...
    CommonHandler,      // 55
    CommonHandler,      // 56
    CommonHandler,      // 57
...
    CommonHandler,      // 254
    CommonHandler       // 255
};

И вручную следить за чистотой этого массива. Найти место для пары новых обработчиков когда все в чистоте не составит никакой сложности. Да и обратная операция - читать этот массив человеку который будет поддерживать код после вас будет легко, - ему не придется бегать к каждой функции и смотреть в какую позицию она загружена.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- AndreyS   Таблица переходов вместо Switch   Mar 23 2010, 15:28
|- - Dog Pawlowa   Цитата(AndreyS @ Mar 23 2010, 22:51) Меня...   Mar 23 2010, 19:25
||- - AndreyS   Цитата(Dog Pawlowa @ Mar 23 2010, 22:25) ...   Mar 23 2010, 19:59
||- - Dog Pawlowa   Цитата(AndreyS @ Mar 23 2010, 23:59) С ва...   Mar 23 2010, 20:07
||- - AndreyS   Цитата(Dog Pawlowa @ Mar 23 2010, 23:07) ...   Mar 23 2010, 20:41
||- - Dog Pawlowa   Цитата(AndreyS @ Mar 24 2010, 00:14) ага....   Mar 23 2010, 20:55
||- - AHTOXA   Цитата(AndreyS @ Mar 24 2010, 01:41) а ка...   Mar 23 2010, 21:54
||- - Dog Pawlowa   Цитата(AHTOXA @ Mar 24 2010, 01:54) Это о...   Mar 23 2010, 22:02
||- - RobFPGA   Приветствую! Цитата(AHTOXA @ Mar 24 201...   Apr 5 2010, 20:36
||- - dxp   Цитата(AHTOXA @ Mar 24 2010, 04:54) работ...   Apr 6 2010, 03:05
||- - AHTOXA   Цитата(dxp @ Apr 6 2010, 09:05) Код// при...   Apr 6 2010, 07:45
||- - dxp   Цитата(AHTOXA @ Apr 6 2010, 14:45) А чем ...   Apr 6 2010, 11:14
||- - AHTOXA   Цитата(dxp @ Apr 6 2010, 17:14) Вот зрась...   Apr 6 2010, 12:15
||- - dxp   Цитата(AHTOXA @ Apr 6 2010, 19:15) А ты х...   Apr 6 2010, 12:56
||- - AHTOXA   Цитата(dxp @ Apr 6 2010, 18:56) Главное, ...   Apr 6 2010, 17:57
||- - dxp   Цитата(AHTOXA @ Apr 7 2010, 01:12) Пришло...   Apr 7 2010, 03:51
||- - AHTOXA   Цитата(dxp @ Apr 7 2010, 10:06) Для new н...   Apr 7 2010, 04:07
||- - dxp   Цитата(AHTOXA @ Apr 7 2010, 11:22) Если n...   Apr 7 2010, 06:24
||- - AHTOXA   Цитата(dxp @ Apr 7 2010, 12:39) А тогда с...   Apr 7 2010, 07:51
||- - dxp   Цитата(AHTOXA @ Apr 7 2010, 15:06) Смысл ...   Apr 7 2010, 13:35
||- - AHTOXA   А, это конечно. Просто наличие new позволяет даже ...   Apr 7 2010, 13:44
||- - dxp   Цитата(AHTOXA @ Apr 7 2010, 20:59) Кодif ...   Apr 8 2010, 03:28
|- - AHTOXA   Цитата(AndreyS @ Mar 24 2010, 00:10) Меня...   Mar 23 2010, 19:38
|- - sonycman   Цитата(AndreyS @ Mar 23 2010, 23:10) опти...   Mar 27 2010, 05:48
||- - AndreyS   Цитата(sonycman @ Mar 27 2010, 09:48) Как...   Mar 29 2010, 08:32
|- - Dog Pawlowa   Цитата(defunct @ Apr 5 2010, 02:56) А что...   Apr 5 2010, 10:24
|- - defunct   Цитата(Dog Pawlowa @ Apr 5 2010, 13:24) Я...   Apr 6 2010, 01:40
|- - Dog Pawlowa   Цитата(defunct @ Apr 6 2010, 04:40) А для...   Apr 6 2010, 07:02
- - baralgin   Цитата(Dog Pawlowa @ Mar 23 2010, 18:30) ...   Mar 23 2010, 17:08
|- - Dog Pawlowa   Цитата(baralgin @ Mar 23 2010, 20:08) По ...   Mar 23 2010, 17:45
|- - zltigo   Цитата(baralgin @ Mar 23 2010, 20:08) По ...   Mar 23 2010, 17:58
- - baralgin   Dog Pawlowa, zltigo, Спасибо, буду знать, а то бол...   Mar 23 2010, 19:18


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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 17:21
Рейтинг@Mail.ru


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