Перейти к содержанию
    

День добрый!

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

 

TABLE

ADDWF PCL,1

RETLW B'11101011' ;0

RETLW B'01100000' ;1

RETLW B'11000111' ;2

RETLW B'11100101' ;3

 

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

Изменено пользователем Algol

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

День добрый!

Недавно начал осваивать Си (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

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

 

psL

Огромное спасибо за ценный пример! Использовать перечислимый тип мне честно сказать даже и в голову не пришло бы. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1.Согласен, что массив в по сравнению с switch - case эффективней.Но здесь надо следить за

индексом.При преобразовании цифр он прекрасно подходит.А если символы?Надо составлять

таблицу для индекса или размещать их согласно своего номера в базе?А если данные берутся из

потока?

2.Надо исходить из конкретного компилятора.Настройте проект на генерацию AS. файла и

посмотрите коды.При разных вариантах на ассемблере.В некоторых случаях даже конструкция IF

эффективней.

3.Что вы имеете под-<<Конструкция switch - case не даст тождественного результата>>?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

И как Вы этот массив описываете? Как доступ к нему осуществляется?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В случае Си, так как посоветовал psL. В случае асма см. первый пост + CALL TABLE

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В случае Си, так как посоветовал psL. В случае асма см. первый пост + CALL TABLE

Я имел в виду Си.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Откуда 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 (одна инструкция ).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Совершенно одинаково

 

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];

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сделал.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В итоге с 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++;}

Изменено пользователем Костян

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...