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

 
 
> Таблица переходов вместо 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
Dog Pawlowa
сообщение Mar 23 2010, 19:25
Сообщение #5


Гуру
******

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



Цитата(AndreyS @ Mar 23 2010, 22:51) *
Меня интересовало как в таблицу, в произвольном порядке прописать адрес функции.

Ну пишете в произвольком порядке и все, вот как я: wink.gif

Код
/ basic functions:
STATE ( Restart            ,    "Restart"          ,  "Neustart"         ,    0        )
STATE ( SelfTest           ,    "Self-test"        ,  "Selbsttest"       , CLR+STN    )
STATE ( Waiting            ,    "Ready"            ,  "Bereit"           ,    0        )
STATE ( AirDeleting        ,    "Air out "         ,  "Entl"uuml"ften"   , CLR+STN    )


Из этой таблицы генерируются и коды, и имена функций, и данные для заполнения массивов.
Только не занимайтесь "ручной" линковкой "а-ля ассемблер".

Цитата(baralgin @ Mar 23 2010, 23:18) *
Изменить в таблице(массив указателей) адрес функции не сложно. ..
mas_func[10] = &new_handler;

Если таким образом программируется машина состояний, но таблицу незачем располагать в памяти данных.
Я понял, что задача автора сделать удобной инициализацию массива. Или?


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


Местный
***

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



Цитата(Dog Pawlowa @ Mar 23 2010, 22:25) *
Ну пишете в произвольком порядке и все, вот как я: wink.gif

Из этой таблицы генерируются и коды, и имена функций, и данные для заполнения массивов.
Только не занимайтесь "ручной" линковкой "а-ля ассемблер".

Я понял, что задача автора сделать удобной инициализацию массива. Или?

ууу. С вашим кодом я поплыл, что такое state я не знаю :-(

я был не полностью откровенен. Keil в данном случае 51 ядро, массив конечно лежит в областе code.

Вы совершенно правы, что задача стоит в удобстве инициализации массива на стадии компиляции(или линковки это не важно, главное что не в процессе выполнения программы).

На асме то я как раз и не хотел делать (это у меня в старых проектах моих, написаных мной на асме). Пишу все время на си, посто потом смотрю что на асме получилось и оптимзирую запись на си, так что бы на асме красиво было (быстро). А со свичем не стал париться, но тут у меня кейс разросся и решил переделать свитчь на таблицу (таблица будет со временем переопределяться, дописываться будут новые обработчики). Вот и хотел написать макрос, который бы сам по числу проверки заносил адрес обработчика в общую таблицу в требуюмую ячейку с замещением в ней адреса дефолтового обработчика. Вот вопрос как?

Цитата(AHTOXA @ Mar 23 2010, 22:38) *
Таким макаром сделаны обработчики прерываний для Cortex-M3 STM32. Для gcc это делается так:
Код
код проглотил

и эта функция попадает в нужное место.


во. Это то что мне нужно. Попробую покрутить в keilе 51.


--------------------
Удачи.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Mar 23 2010, 20:07
Сообщение #7


Гуру
******

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



Цитата(AndreyS @ Mar 23 2010, 23:59) *
С вашим кодом я поплыл, что такое state я не знаю :-(

Это просто мой макрос, определение которого меняется в программе несколько раз.
Не "грязный хак", но любители строгого С обычно стоят в сторонке. smile.gif


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


Местный
***

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



Цитата(Dog Pawlowa @ Mar 23 2010, 23:07) *
Это просто мой макрос, определение которого меняется в программе несколько раз.
Не "грязный хак", но любители строгого С обычно стоят в сторонке. smile.gif


ага. Значит читать мне надо про макросы?

Цитата(AHTOXA @ Mar 23 2010, 22:38) *
Таким макаром сделаны обработчики прерываний для Cortex-M3 STM32. Для gcc это делается так:
...
и эта функция попадает в нужное место.

а как бы к этому математику подтянут?. Пример. Имеем команду ENTER, она имеет числовое значение равное 10. Получается что ее обработчик f10. А теперь положим сменилось ее числовое значение на другое. Получается нужно не забыть переименовать обработчик.
Как бы привязать заполнение таблицы к номеру команды? И исходя из ее значения в соответствующую ячейку таблицы попадал адрес обработчика. Сменил я номер команды и адрес автоммтом лег в новую ячейку, а в старую опять вернулся адрес дефаулт обработчика.

Сообщение отредактировал rezident - Mar 24 2010, 01:39
Причина редактирования: Нарушение п.3.4 Правил форума.


--------------------
Удачи.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Mar 23 2010, 21:54
Сообщение #9


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(AndreyS @ Mar 24 2010, 01:41) *
а как бы к этому математику подтянут?. Пример. Имеем команду ENTER, она имеет числовое значение равное 10. Получается что ее обработчик f10. А теперь положим сменилось ее числовое значение на другое. Получается нужно не забыть переименовать обработчик.
Как бы привязать заполнение таблицы к номеру команды?


Ну это уже мелочиsmile.gif

Код
#define DECLARE_COMMAND_HANDLER2(cmd_number) void f##cmd_number(void)
#define DECLARE_COMMAND_HANDLER(cmd_number) DECLARE_COMMAND_HANDLER2(cmd_number)

#define CMD_ENTER  10

DECLARE_COMMAND_HANDLER(CMD_ENTER)
{
  for (;;);
}


Код
DECLARE_COMMAND_HANDLER(CMD_ENTER)

развернётся в
Код
void f10(void)


При смене CMD_ENTER на 20 - станет
Код
void f20(void)
.


Цитата(Dog Pawlowa @ Mar 24 2010, 01:55) *
В простейшем виде пишете
#define f25 /*empty_function*/my_function_for_code_25


Это отличный вариант, пока все обработчики хранятся в одном файле. Но иногда (часто) нужно, чтоб модуль при подключении автоматически добавлял свой элемент в таблицу. В случае фиксированной таблицы (с известным заранее числом элементов, типа таблицы векторов прерываний) - можно применить вариант, который я привёл. А вот для произвольной таблицы - я так ничего путного и не придумал.
А как было бы здорово, если бы модуль (.c файл) мог при его добавлении в проект, скажем, автоматически добавить несколько своих терминальных команд, пару переменных в конфиг, етцsmile.gif
Придумалось только для плюсов, через смесь шаблонов и макросов. Да и то не всё там гладко, накладные расходы по ОЗУ (не всё во флеше), и работоспособность зависит от порядка вызова глобальных конструкторов (не определён стандартом, емнимс).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 6 2010, 03:05
Сообщение #10


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(AHTOXA @ Mar 24 2010, 04:54) *
работоспособность зависит от порядка вызова глобальных конструкторов (не определён стандартом, емнимс).

С этим можно побороться с помощью паттерна Singleton.

Код
//---------------------------------------------------------------------------
template<typename T> class singleton
{
public:
    static T& Instance() { static T instance; return instance; }
};
//---------------------------------------------------------------------------


Использование:

Код
class TSlon { ... };


TSlon& slon = singleton<TSlon>::Instance();

// далее идет использование слона (синтаксически как обычный объект):
// при создании ссылки внутри singleton<TSlon> будет
// статически создан и проинициализирован объект внутри Instance(), поэтому
// ссылку можно безопасно использовать

Есть небольшие накладняки на создание статического объекта, но они небольшие - соизмеримы с вызовом конструктора. Работает этот прием очень хорошо.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 6 2010, 07:45
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Apr 6 2010, 09:05) *
Код
// при создании ссылки внутри singleton<TSlon> будет
// статически создан и проинициализирован объект внутри Instance(), поэтому
// ссылку можно безопасно использовать


А чем нам поможет замена глобального объекта на глобальный статический? В плане руления порядком вызова конструкторов? То есть, чем это отличается от простого объявления
Код
TSlon slon;
?
Имхо, без динамического создания объектов singleton совершенно бесполезен.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 6 2010, 11:14
Сообщение #12


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(AHTOXA @ Apr 6 2010, 14:45) *
А чем нам поможет замена глобального объекта на глобальный статический? В плане руления порядком вызова конструкторов? То есть, чем это отличается от простого объявления

Вот зрасьте! В этом же вся фишка синглтона. Когда какой-то объект нуждается в объекте TSlon, то он создает (использует) ссылку, возвращаемую функцией Instance() шаблона singleton. А ссылка эта ссылается на статический объект, создаваемый внутри фукнции-члена Instance(). Таким образом, получается следующая схема: при первом вызове Instance() будет создан и проинициализирован статический объект требуемого типа (в нашем примере TSlon), все последующие вызовы будут возвращать ссылку на уже существующий объект. И не важно, кто первый дернул Instance(), думать об этом не надо. В этом и избавление от зависимости от порядка вызова конструкторов.

Цитата(AHTOXA @ Apr 6 2010, 14:45) *
Код
TSlon slon;
?
Имхо, без динамического создания объектов singleton совершенно бесполезен.

Еще как полезен: объект создается как статический внутри статической же функции-члена Instance(). И живет там все время, пока программа работает. Т.е. по сути как обынчый глобальный объект, но спрятанный внутри функции и предоставляющий доступ по ссылке (что синтаксически ровно как доступ к обычному объекту). Нету тут ни работы с кучей, ни выделения памяти на рантайме. Выделение памяти и инициализация производятся комилятором на основе правил языка в части статических объектов внутри функций (которые есть даже в голом С).


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 6 2010, 12:15
Сообщение #13


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Apr 6 2010, 17:14) *
Вот зрасьте! В этом же вся фишка синглтона.


Упс. Я был уверен, что разница между статическим и глобальным объектом только в области видимости.
А ты хочешь сказать, что для статических объектов конструкторы вызываются не в списке глобальных конструкторов, а при первом вызове функции, в которой он содержится? Если так, то это супер! Надо проверитьsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 6 2010, 12:56
Сообщение #14


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(AHTOXA @ Apr 6 2010, 19:15) *
А ты хочешь сказать, что для статических объектов конструкторы вызываются не в списке глобальных конструкторов, а при первом вызове функции, в которой он содержится? Если так, то это супер! Надо проверитьsmile.gif

Статический объект должен быть гарантировано проинициализирован до его использования. А где это делается - отдано на откуп реализации. Например:
Код
void f()
{
    int a = 10;
    ... // код функции
}

Реализация может быть разной. Самое простое - сунуть а в секцию, где помещаются глобальные переменные, и проинициализировать вместе с ними (IAR, помнится, так и делает) - разница тут будет только в области видимости. А можно тут вставить код, проверяющий первый вход в функцию, и вызывать инициализатор (это тот самый оверхед, про который я говорил, и который незначителен по сравнению с вызовом конструктора). Как делается реально в том или ином случае - это в ведении реализации (в случае с вызовом конструктора объекта пользовательского типа скорее всего делается по второму варианту). Главное, что поведение четко стандартизовано и это можно безопасно использовать.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 6 2010, 17:57
Сообщение #15


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Apr 6 2010, 18:56) *
Главное, что поведение четко стандартизовано и это можно безопасно использовать.


Попробовал, получилось. Но далеко не сразу. Простая замена глобального объекта
Код
uart1_t uart1;

на ссылку:
Код
uart1_t& uart1 = singleton<uart1_t>::Instance();

Не прокатила. Потому что теперь вместо глобального объекта uart1 у нас получилась глобальная же ссылкаsmile.gif Порядок инициализации которой (на этот раз при помощи хитрого синглетона!) по прежнему не определён.
Пришлось везде, где используется uart1, заводить локальные переменные-ссылки
Код
uart1_t& localuart = singleton<uart1_t>::Instance();

и использовать их. Вот тогда всё заработало должным образомsmile.gif
Что касаемо накладных расходов, то они достаточно приличные:
Код
*с глобальным uart:
   text    data     bss     dec     hex filename
   4372       8    5792   10172    27bc ./exe/stm32-H103.elf
*с singleton<uart1_t>:
   text    data     bss     dec     hex filename
   4500       8    5800   10308    2844 ./exe/stm32-H103.elf

(Всё это gcc на stm32)

Я думаю, что для некоторых применений это хорошее решение, по крайней мере я намерен его применять.
(Или всё же new? smile.gif )


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 7 2010, 03:51
Сообщение #16


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(AHTOXA @ Apr 7 2010, 01:12) *
Пришлось везде, где используется uart1, заводить локальные переменные-ссылки
Код
uart1_t& localuart = singleton<uart1_t>::Instance();

и использовать их. Вот тогда всё заработало должным образомsmile.gif

Конечно, именно так и надо делать, в этом и смысл. Точнее, глобальную ссылку завести тоже не лишне, но ее использовать по ходу программы, а вот в конструкторах - да, только локальные ссылки.

Цитата(AHTOXA @ Apr 7 2010, 01:12) *
Я думаю, что для некоторых применений это хорошее решение, по крайней мере я намерен его применять.
(Или всё же new? smile.gif )

Для new надо свой быстрый и не подверженный фрагментации менеджер памяти сделать. Если только для вышеописанных целей, то это будет еще больше накладных. А вообще такой мененжер памяти местами очень полезен. Надо будет сделать, как руки дойдут.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 7 2010, 04:07
Сообщение #17


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Apr 7 2010, 10:06) *
Для new надо свой быстрый и не подверженный фрагментации менеджер памяти сделать. Если только для вышеописанных целей, то это будет еще больше накладных. А вообще такой мененжер памяти местами очень полезен.


Если new будет использоваться только как замена глобальным объектам, то фрагментация ему не грозит, ибо будет только new, без delete. Но если
Цитата
Надо будет сделать, как руки дойдут.

, то я только заsmile.gif
ЗЫ. Пока прикрутил bget, вроде работает.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 7 2010, 06:24
Сообщение #18


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(AHTOXA @ Apr 7 2010, 11:22) *
Если new будет использоваться только как замена глобальным объектам, то фрагментация ему не грозит, ибо будет только new, без delete.

А тогда смысла нет в динамическом управлении памятью. Смысл ведь в том, чтобы юзать одну и ту же память под разные цели в разные моменты времени. Как стек, только со временем жизни объектов, определяемым пользователем. А если без delete, то тот вариант во статиками внутри получается функционально почти такой же, а по накладным лучше.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 7 2010, 07:51
Сообщение #19


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Apr 7 2010, 12:39) *
А тогда смысла нет в динамическом управлении памятью. Смысл ведь в том, чтобы юзать одну и ту же память под разные цели в разные моменты времени.

Смысл в том, что объекты создаются в нужном мне порядке, я управляю этим.
Насчёт увеличения накладных - это вряд ли. ну разве что при создании объекта. При работе - простейшая проверка на null и возврат.
Естественно, если будут нормальные new/delete, то лучше использовать их.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- AndreyS   Таблица переходов вместо Switch   Mar 23 2010, 15:28
||- - Dog Pawlowa   Цитата(AndreyS @ Mar 24 2010, 00:14) ага....   Mar 23 2010, 20:55
||- - 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 @ 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
|- - defunct   Цитата(AndreyS @ Mar 23 2010, 22:10) Тепе...   Apr 4 2010, 23:56
|- - 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 Текстовая версия Сейчас: 21st July 2025 - 17:30
Рейтинг@Mail.ru


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