|
Таблицы, как сделать на Си? |
|
|
|
Jul 31 2006, 10:29
|
Знающий
   
Группа: Свой
Сообщений: 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];
|
|
|
|
|
Aug 1 2006, 12:54
|
Местный
  
Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219

|
Цитата(Algol @ Aug 1 2006, 09:30)  По п.1 согласен, что с буквами будут дополнительные сложности, но в данном случае мне трубовались только цифры. Под тождественным результатом, я имел ввиду производительность, т.е. эффект от IF будет тот же что и от массива, а быстродействие ниже.
По поводу п.3 провел сейчас небольшое исследование сгенеринного кода. В общем то массив представляется как и надо - командами retlw. Однако на его организацию уходит около 60 байт!!! Сравнил с кодом на асме - там всего 13 байт для 10 цифр. И как Вы этот массив описываете? Как доступ к нему осуществляется?
|
|
|
|
|
Aug 1 2006, 13:16
|
Местный
  
Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219

|
Цитата(Algol @ Aug 1 2006, 16:05)  В случае Си, так как посоветовал psL. В случае асма см. первый пост + CALL TABLE Я имел в виду Си.
|
|
|
|
|
Aug 3 2006, 15:19
|
Знающий
   
Группа: Свой
Сообщений: 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 (одна инструкция ).
|
|
|
|
|
Aug 4 2006, 05:06
|
Участник

Группа: Новичок
Сообщений: 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]; }
|
|
|
|
|
Aug 4 2006, 09:56
|
Знающий
   
Группа: Свой
Сообщений: 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
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|