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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Таблицы, как сделать на Си?
Algol
сообщение Jul 31 2006, 08:28
Сообщение #1


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

Группа: Свой
Сообщений: 140
Регистрация: 7-04-05
Из: Россия, Владимир
Пользователь №: 3 941



День добрый!
Недавно начал осваивать Си (HT-PICC) и все было хорошо, пока мне не приспичило сделать таблицу перекодировки. На асме я писал вот так, все просто и понятно - перед вызовом процедуры кидаем в W цифру, образ которой хотим получить

TABLE
ADDWF PCL,1
RETLW B'11101011' ;0
RETLW B'01100000' ;1
RETLW B'11000111' ;2
RETLW B'11100101' ;3

Вопрос к знатокам, как мне сделать тоже самое, но только на Си?

Сообщение отредактировал Algol - Jul 31 2006, 08:29
Go to the top of the page
 
+Quote Post
psL
сообщение Jul 31 2006, 10:29
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390



Цитата(Algol @ Jul 31 2006, 12:28) *
День добрый!
Недавно начал осваивать Си (HT-PICC) и все было хорошо, пока мне не приспичило сделать таблицу перекодировки. На асме я писал вот так, все просто и понятно - перед вызовом процедуры кидаем в W цифру, образ которой хотим получить

TABLE
ADDWF PCL,1
RETLW B'11101011' ;0
RETLW B'01100000' ;1
RETLW B'11000111' ;2
RETLW B'11100101' ;3

Вопрос к знатокам, как мне сделать тоже самое, но только на Си?


char conv[]={ 0xEB, 0x60, 0xA7, 0xE5 };

...

char in=1;
char out=conv[in];
Go to the top of the page
 
+Quote Post
upc2
сообщение Jul 31 2006, 12:07
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



Использовать конструкцию "switch case"
Go to the top of the page
 
+Quote Post
Algol
сообщение Jul 31 2006, 14:12
Сообщение #4


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

Группа: Свой
Сообщений: 140
Регистрация: 7-04-05
Из: Россия, Владимир
Пользователь №: 3 941



upc2
Конструкция switch - case не даст тождественного результата, хотя это самый очевидный путь. Работать будет, но с потерей производительности прямо пропорционально объему таблицы. Но все равно, спасибо, за совет.

psL
Огромное спасибо за ценный пример! Использовать перечислимый тип мне честно сказать даже и в голову не пришло бы. smile.gif
Go to the top of the page
 
+Quote Post
upc2
сообщение Aug 1 2006, 06:00
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



1.Согласен, что массив в по сравнению с switch - case эффективней.Но здесь надо следить за
индексом.При преобразовании цифр он прекрасно подходит.А если символы?Надо составлять
таблицу для индекса или размещать их согласно своего номера в базе?А если данные берутся из
потока?
2.Надо исходить из конкретного компилятора.Настройте проект на генерацию AS. файла и
посмотрите коды.При разных вариантах на ассемблере.В некоторых случаях даже конструкция IF
эффективней.
3.Что вы имеете под-<<Конструкция switch - case не даст тождественного результата>>?
Go to the top of the page
 
+Quote Post
Algol
сообщение Aug 1 2006, 06:30
Сообщение #6


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

Группа: Свой
Сообщений: 140
Регистрация: 7-04-05
Из: Россия, Владимир
Пользователь №: 3 941



По п.1 согласен, что с буквами будут дополнительные сложности, но в данном случае мне трубовались только цифры.
Под тождественным результатом, я имел ввиду производительность, т.е. эффект от IF будет тот же что и от массива, а быстродействие ниже.

По поводу п.3 провел сейчас небольшое исследование сгенеринного кода. В общем то массив представляется как и надо - командами retlw. Однако на его организацию уходит около 60 байт!!! Сравнил с кодом на асме - там всего 13 байт для 10 цифр.
Go to the top of the page
 
+Quote Post
_Bill
сообщение Aug 1 2006, 12:54
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(Algol @ Aug 1 2006, 09:30) *
По п.1 согласен, что с буквами будут дополнительные сложности, но в данном случае мне трубовались только цифры.
Под тождественным результатом, я имел ввиду производительность, т.е. эффект от IF будет тот же что и от массива, а быстродействие ниже.

По поводу п.3 провел сейчас небольшое исследование сгенеринного кода. В общем то массив представляется как и надо - командами retlw. Однако на его организацию уходит около 60 байт!!! Сравнил с кодом на асме - там всего 13 байт для 10 цифр.

И как Вы этот массив описываете? Как доступ к нему осуществляется?
Go to the top of the page
 
+Quote Post
Algol
сообщение Aug 1 2006, 13:05
Сообщение #8


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

Группа: Свой
Сообщений: 140
Регистрация: 7-04-05
Из: Россия, Владимир
Пользователь №: 3 941



В случае Си, так как посоветовал psL. В случае асма см. первый пост + CALL TABLE
Go to the top of the page
 
+Quote Post
_Bill
сообщение Aug 1 2006, 13:16
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(Algol @ Aug 1 2006, 16:05) *
В случае Си, так как посоветовал psL. В случае асма см. первый пост + CALL TABLE

Я имел в виду Си.
Go to the top of the page
 
+Quote Post
upc2
сообщение Aug 2 2006, 08:09
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



Откуда 60 байт?
Программа на Си

void main(void)
{
char in,out;
char conv[]={0xEB,0x60,0xE5};
in=1;
out=conv[in];

}


Вот , что сделал компилятор PICC PL8.05



1 0000 0183 CLRF 0x3
2 0001 3000 MOVLW 0
3 0002 008A MOVWF 0xa
4 0003 2804 GOTO 0x4
5 0004 0183 CLRF 0x3
6 0005 2BF4 GOTO 0x3f4
.........................


1013 03F4 30EB MOVLW 0xeb
1014 03F5 1283 BCF 0x3, 0x5
1015 03F6 008E MOVWF 0xe
1016 03F7 3060 MOVLW 0x60
1017 03F8 008F MOVWF 0xf
1018 03F9 30E5 MOVLW 0xe5
1019 03FA 0090 MOVWF 0x10
1020 03FB 018C CLRF 0xc
1021 03FC 0A8C INCF 0xc, F
1022 03FD 080F MOVF 0xf, W
1023 03FE 008D MOVWF 0xd
1024 03FF 2804 GOTO 0x4
Go to the top of the page
 
+Quote Post
Костян
сообщение Aug 3 2006, 15:19
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 740
Регистрация: 24-07-06
Из: Minsk
Пользователь №: 19 059



Цитата(psL @ Jul 31 2006, 08:29) *
char conv[]={ 0xEB, 0x60, 0xA7, 0xE5 };

...

char in=1;
char out=conv[in];


Для таблиц экономичней так
const conv[]={ 0xEB, 0x60, 0xA7, 0xE5 };
...

char in=1;
char out=conv[in];

В итоге код в два раза меньше. В первом случае нужно сохранить значение и записать его в ОЗУ (две инструкции. Во втором случае только retlw (одна инструкция ).
Go to the top of the page
 
+Quote Post
upc2
сообщение Aug 4 2006, 05:01
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



С точки зрения экономичности совершенно одинаково,

void main(void)
{
char out;
const char conv[]={0xEB,0x60,0xE5};
char in=1;
out=conv[in];
}


2 0001 3000 MOVLW 0
3 0002 008A MOVWF 0xa
4 0003 2804 GOTO 0x4
5 0004 0183 CLRF 0x3
6 0005 2BF7 GOTO 0x3f7
7 0006 0782 ADDWF 0x2, F
8 0007 34EB RETLW 0xeb
9 0008 3460 RETLW 0x60
10 0009 34E5 RETLW 0xe5
....................................

1016 03F7 1283 BCF 0x3, 0x5
1017 03F8 018C CLRF 0xc
1018 03F9 0A8C INCF 0xc, F
1019 03FA 3000 MOVLW 0
1020 03FB 008A MOVWF 0xa
1021 03FC 3001 MOVLW 0x1
1022 03FD 2006 CALL 0x6
1023 03FE 008D MOVWF 0xd
1024 03FF 2804 GOTO 0x4

но согласен с быстродействием выполнения программы.

Сообщение отредактировал upc2 - Aug 4 2006, 05:06
Go to the top of the page
 
+Quote Post
dialex
сообщение Aug 4 2006, 05:06
Сообщение #13


Участник
*

Группа: Новичок
Сообщений: 22
Регистрация: 11-07-06
Пользователь №: 18 734



Цитата(upc2 @ Aug 4 2006, 10:01) *
Совершенно одинаково

void main(void)
{
char out;
const char conv[]={0xEB,0x60,0xE5};
char in=1;
out=conv[in];
}


2 0001 3000 MOVLW 0
3 0002 008A MOVWF 0xa
4 0003 2804 GOTO 0x4
5 0004 0183 CLRF 0x3
6 0005 2BF7 GOTO 0x3f7
7 0006 0782 ADDWF 0x2, F
8 0007 34EB RETLW 0xeb
9 0008 3460 RETLW 0x60
10 0009 34E5 RETLW 0xe5
....................................

1016 03F7 1283 BCF 0x3, 0x5
1017 03F8 018C CLRF 0xc
1018 03F9 0A8C INCF 0xc, F
1019 03FA 3000 MOVLW 0
1020 03FB 008A MOVWF 0xa
1021 03FC 3001 MOVLW 0x1
1022 03FD 2006 CALL 0x6
1023 03FE 008D MOVWF 0xd
1024 03FF 2804 GOTO 0x4

сделай так
const char conv[]={0xEB,0x60,0xE5};
char out;
void main(void)
{
char in=1;
out=conv[in];
}
Go to the top of the page
 
+Quote Post
upc2
сообщение Aug 4 2006, 05:19
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 29-09-05
Из: Донецк
Пользователь №: 9 063



Сделал.

3 0002 008A MOVWF 0xa
4 0003 2804 GOTO 0x4
5 0004 300C MOVLW 0xc
6 0005 0084 MOVWF 0x4
7 0006 300E MOVLW 0xe
8 0007 200D CALL 0xd
9 0008 0183 CLRF 0x3
10 0009 2BF7 GOTO 0x3f7
11 000A 0604 XORWF 0x4, W
12 000B 0180 CLRF 0
13 000C 0A84 INCF 0x4, F
14 000D 0604 XORWF 0x4, W
15 000E 1D03 BTFSS 0x3, 0x2
16 000F 280A GOTO 0xa
17 0010 3400 RETLW 0
18 0011 0782 ADDWF 0x2, F
19 0012 34EB RETLW 0xeb
20 0013 3460 RETLW 0x60
21 0014 34E5 RETLW 0xe5
.............................................
1016 03F7 1283 BCF 0x3, 0x5
1017 03F8 018D CLRF 0xd
1018 03F9 0A8D INCF 0xd, F
1019 03FA 3000 MOVLW 0
1020 03FB 008A MOVWF 0xa
1021 03FC 3001 MOVLW 0x1
1022 03FD 2011 CALL 0x11
1023 03FE 008C MOVWF 0xc
1024 03FF 2804 GOTO 0x4
Go to the top of the page
 
+Quote Post
Костян
сообщение Aug 4 2006, 09:56
Сообщение #15


Знающий
****

Группа: Свой
Сообщений: 740
Регистрация: 24-07-06
Из: Minsk
Пользователь №: 19 059



В итоге с const мы видем наличие 'retlw0x60'. Без нее:MOVLW 0x60 MOVWF 0xf . Получаем экономию в два раза + не забиваем ОЗУ.

Лучше наблюдать на большом обьеме данных (около 100 единиц).

Например:
const conv[]={ 0xEB, 0x60, 0xA7, 0xE5,.......................................,'~' };
...
unsigned char in=0;
while (conv[in]!='~') {PORTB=conv[in];in++;}



сравниваем с (незабываем смотреть на ОЗУ):

char conv[]={ 0xEB, 0x60, 0xA7, 0xE5,.......................................,'~' };
...
unsigned char in=0;
while (conv[in]!='~') {PORTB=conv[in];in++;}


Сообщение отредактировал Костян - Aug 4 2006, 09:59
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:19
Рейтинг@Mail.ru


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