Algol 0 31 июля, 2006 Опубликовано 31 июля, 2006 (изменено) · Жалоба День добрый! Недавно начал осваивать Си (HT-PICC) и все было хорошо, пока мне не приспичило сделать таблицу перекодировки. На асме я писал вот так, все просто и понятно - перед вызовом процедуры кидаем в W цифру, образ которой хотим получить TABLE ADDWF PCL,1 RETLW B'11101011' ;0 RETLW B'01100000' ;1 RETLW B'11000111' ;2 RETLW B'11100101' ;3 Вопрос к знатокам, как мне сделать тоже самое, но только на Си? Изменено 31 июля, 2006 пользователем Algol Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 31 июля, 2006 Опубликовано 31 июля, 2006 · Жалоба День добрый! Недавно начал осваивать Си (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]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
upc2 0 31 июля, 2006 Опубликовано 31 июля, 2006 · Жалоба Использовать конструкцию "switch case" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Algol 0 31 июля, 2006 Опубликовано 31 июля, 2006 · Жалоба upc2 Конструкция switch - case не даст тождественного результата, хотя это самый очевидный путь. Работать будет, но с потерей производительности прямо пропорционально объему таблицы. Но все равно, спасибо, за совет. psL Огромное спасибо за ценный пример! Использовать перечислимый тип мне честно сказать даже и в голову не пришло бы. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
upc2 0 1 августа, 2006 Опубликовано 1 августа, 2006 · Жалоба 1.Согласен, что массив в по сравнению с switch - case эффективней.Но здесь надо следить за индексом.При преобразовании цифр он прекрасно подходит.А если символы?Надо составлять таблицу для индекса или размещать их согласно своего номера в базе?А если данные берутся из потока? 2.Надо исходить из конкретного компилятора.Настройте проект на генерацию AS. файла и посмотрите коды.При разных вариантах на ассемблере.В некоторых случаях даже конструкция IF эффективней. 3.Что вы имеете под-<<Конструкция switch - case не даст тождественного результата>>? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Algol 0 1 августа, 2006 Опубликовано 1 августа, 2006 · Жалоба По п.1 согласен, что с буквами будут дополнительные сложности, но в данном случае мне трубовались только цифры. Под тождественным результатом, я имел ввиду производительность, т.е. эффект от IF будет тот же что и от массива, а быстродействие ниже. По поводу п.3 провел сейчас небольшое исследование сгенеринного кода. В общем то массив представляется как и надо - командами retlw. Однако на его организацию уходит около 60 байт!!! Сравнил с кодом на асме - там всего 13 байт для 10 цифр. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bill 0 1 августа, 2006 Опубликовано 1 августа, 2006 · Жалоба По п.1 согласен, что с буквами будут дополнительные сложности, но в данном случае мне трубовались только цифры. Под тождественным результатом, я имел ввиду производительность, т.е. эффект от IF будет тот же что и от массива, а быстродействие ниже. По поводу п.3 провел сейчас небольшое исследование сгенеринного кода. В общем то массив представляется как и надо - командами retlw. Однако на его организацию уходит около 60 байт!!! Сравнил с кодом на асме - там всего 13 байт для 10 цифр. И как Вы этот массив описываете? Как доступ к нему осуществляется? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Algol 0 1 августа, 2006 Опубликовано 1 августа, 2006 · Жалоба В случае Си, так как посоветовал psL. В случае асма см. первый пост + CALL TABLE Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bill 0 1 августа, 2006 Опубликовано 1 августа, 2006 · Жалоба В случае Си, так как посоветовал psL. В случае асма см. первый пост + CALL TABLE Я имел в виду Си. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
upc2 0 2 августа, 2006 Опубликовано 2 августа, 2006 · Жалоба Откуда 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Костян 0 3 августа, 2006 Опубликовано 3 августа, 2006 · Жалоба 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 (одна инструкция ). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
upc2 0 4 августа, 2006 Опубликовано 4 августа, 2006 (изменено) · Жалоба С точки зрения экономичности совершенно одинаково, 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 но согласен с быстродействием выполнения программы. Изменено 4 августа, 2006 пользователем upc2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dialex 0 4 августа, 2006 Опубликовано 4 августа, 2006 · Жалоба Совершенно одинаково 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]; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
upc2 0 4 августа, 2006 Опубликовано 4 августа, 2006 · Жалоба Сделал. 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Костян 0 4 августа, 2006 Опубликовано 4 августа, 2006 (изменено) · Жалоба В итоге с 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++;} Изменено 4 августа, 2006 пользователем Костян Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться