Hу сейчас я вам урок грамотного программирования даду ;) - Page 8

Do you have a question? Post it now! No Registration Necessary

Threaded View
Re: Hy сейчас я вам ypок гpамотного пpогpаммиpования дадy ;)
Дима, приветствую!

Quoted text here. Click to load it
Не знаю. Этот я выдрал из модуля сцениковской виртуальной периферии IrDA.
Запустил - работает. В описании IrLAP сказано, что "This field contains a 16
bit CRC-CCITT cyclic redundancy check.".  И
"The HDLC polynomial: x**0 + x**5 + x**12 + x**16 (0x8408)."



С уважением,
 Сергей Борщ



--
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru

Re: Hy сейчас я вам ypок гpамотного пpогpаммиpования дадy ;)
4-Feb-04 07:34 Dimmy Timchenko wrote to Sergey A. Borshch:

 SAB>> Кто там грозился таблицу в полином пересчитать???
 SAB>> То, что ты поскипал - это алгоритм рассчета стандартной CRC CCITT

DT> Кстати, а есть места, где лежат такие вот изящные алгоритмы?

RU.EMBEDDED :-)

Эту CRC16 впервые кидал сюда Акулин году в 97 или 98 :-)

wbr,
--
/* Oleksandr Redchuk, Brovary, Ukraine */
/* real '\x40' real '\x2E' kiev '\x2E' ua     */


Re: Hy сейчас я вам ypок гpамотного пpогpаммиpования дадy ;)
Милостивый государь Dimmy!

04 Фев 04 07:34, Вы изволили послать сюда, в частности, следующее:

 SAB>> Кто там грозился таблицу в полином пересчитать???
 SAB>> То, что ты поскипал - это алгоритм рассчета стандартной CRC CCITT
 DT> Кстати, а есть места, где лежат такие вот изящные алгоритмы?

CCITT - это девичья фамилия. Hыне ITU-T (МСЭ-Т, международный союз
электросвязи, отдел телекоммуникаций). Ежели у кого есть потребности,
подкрепленные указанием номера конкретной рекомендации - welcome на origin.

Примите уверения в совершеннейшем к Вам почтении. А.П.Гуськов.


Re: Hy сейчас я вам ypок гpамотного пpогpаммиpования дадy ;)
    Hello, Sergey!

Втp Фев 03 2004, Sergey A. Borshch писал к Maxim Polyanskiy по поводу "Re: Hy
сейчас я вам ypок гpамотного пpогpаммиpования дадy ;)."
 >> x = ((crc>>8)^d)&0xff;
 >>   x ^= x>> 4;
 >> crc = (crc<<8)^(x<<12)^(x<<5)^x;
 SB> Во-первых, ты написал другой алгоритм (для потоков младшим битом
 SB> вперед).
Значит ты ошибся. Это его алгоритм - можешь сдвиги посчитать.
 SB> Во-вторых, он не работает.
Да ну. В каком месте?
 SB> Тебе было предложено описание на языке C оптимизированного алгоритма.
 SB> Ты же предлагаешь писать его "в лоб". Hе есть честно.
Окей - я не оптимизирую асм алгоримы а вы не заявляете что Cи - язык понятный
абсолютно всем ламерам мира!
 SB> А несколько точек входа С-компилятор тоже делает. Hапример, при
 SB> компиляции switch() у которого несколько case имеют одинаковые
 SB> окончания.
Еще раз - мне нужно откомпилированный код примера который я постил - хоть на
каком проце! чтоб процедура там указанная имела несколько точек входа. Тогда мы
с удовольствием это обсудим. Как оно там в теории - не интересно. А что касаемо
switch () - так это самый жирный источник оверхеда любых прог.
 SB> АОH "Русь" действительно пишут на асме. Вчера беседовал с одним из
 SB> создателей нового кристалла, заточенного под АОH:
Hу вот. Я думал, что тему "изобретения кристалов под задачу" мы будем
обсуждать, когда вы облажаетесь предложить 2-х баксовый авр (или еще что) с
256к памяти... А ты зашел с тыла и весь кайф сломал. ;)

 SB>  а основная причина - это то, что нам асм просто
 SB> удобнее, привычнее и т.д. чем С. Да и какой С когда под стек 10-12
 SB> байт дают, и то в пике.

А чего ты ждал - наши люди!

 SB> Сергей Борщ
  WBR!  Maxim Polyanskiy.


Re: Hy сейчас я вам ypок гpамотного пpогpаммиpования дадy ;)
Максим, приветствую!

Quoted text here. Click to load it
Не, сдвиги я считать не стал. См дальше.
Quoted text here. Click to load it
 Я натравил Димин и твой алгоритмы на строку "Tipa test" и получил два
разных числа на выходе. Если Димин алгоритм работает у меня в реализации
стека IrDA (на С,кстати), а также для общения с радиомодемом CMX909, я делаю
вывод, что твой работать не будет.

Quoted text here. Click to load it
понятный
Quoted text here. Click to load it
Годится. Я лично никогда не буду такого утверждать, и убедю никогда так не
говорить AM, OR, AB и прочих твоих оппонентов. Обещаешь, что не будешь
оптимизировать алгоритмы ;-))?
Кстати, они говорили, что язык понятен тем, кто его знает.

Quoted text here. Click to load it
на
Quoted text here. Click to load it
Попробовал на нескольких. Двух точек входа нет. В одном случае последний
call сэкономил. Но! компилятор сделал это быстрее меня, помня какие операции
можно применять к каким регистрам, а какие - нет, помня на какие флаги
влияет каждая команда и прочее и прочее.

Quoted text here. Click to load it
Не имеет смысла. Ты никого не переубедишь, мы тебя - тоже.

Quoted text here. Click to load it

На _крайний_ случай ничего не мешает написать ее на асме (если скорость
критична) и объявить ее для С как две разные extern. У меня так обмен в
софтовом I2C сделан. функция перекачки байта - на асме, остальное - на С. А
можно написать на С, взять листинг и его оптимизнуть. Это будет куда
быстрее, чем писать на асме с нуля.

Quoted text here. Click to load it
прог.
Стек IrDA у меня построен на 8 или 9 switch(). Вложенных. Я бы на асме во
многих местах не догадался так соптимизировать, как это сделал компилятор.
Ну нет у него в case оверхеда! И перекинул я его с MSP на x51 за 2 часа
(долго вспоминал, какие памяти у 51 есть и как их обзывать). А расчет CRC
(который выше был упомянут) просто ctrl-c, ctrl-v в прогу для AVR. А потом
получившуюся расшифровку пакетов радиомодема ctrl-c, ctrl-v в прогу для MSP.

Не, я больше спорить не буду - надо работу работать.

 Сергей Борщ




--
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru

Re: Hy сейчас я вам ypок гpамотного пpогpаммиpования дадy ;)
4-Feb-04 18:03 Sergey A. Borshch wrote to Maxim Polyanskiy:

SB> Годится. Я лично никогда не буду такого утверждать, и убедю никогда так
SB> не
SB> говорить AM, OR, AB и прочих твоих оппонентов. Обещаешь, что не будешь
SB> оптимизировать алгоритмы ;-))?
SB> Кстати, они говорили, что язык понятен тем, кто его знает.
 Естественно. А ламеры вообще в рассчёт не берутся, они всё равно на
любом языке муру напишут.


Quoted text here. Click to load it

SB> Попробовал на нескольких. Двух точек входа нет. В одном случае последний
 IAR C / AVR 1.40 при "правильном" размещении функций делает
две точки входа и один ret без rjmp
Пример брошен рядом.

SB> рассчёт CRC
SB> (который выше был упомянут) просто ctrl-c, ctrl-v в прогу для AVR. А
 он (crc16.c crc16.asm) у меня вообще в /common лежит и берётся оттуда
борланд-сём для dll-ки на PC, которая через пару радиомодемов с 89c51rc
общается, и кейлом для этого 89c51, и avr-gcc для другого устройства
на 90s8515, которое с другой dll-кой в PC общается. Без никаких ^C^V
вообще.

wbr,
--
/* Oleksandr Redchuk, Brovary, Ukraine */
/* real '\x40' real '\x2E' kiev '\x2E' ua     */


Re: Hу сейчас я вам урок грамотного программирования даду ;)
    Hello, Andy!

Сpд Янв 28 2004, Andy Mozzhevilov писал к Maxim Polyanskiy по  поводу "Re: Hу
сейчас я вам урок грамотного программирования даду ;)."
 MP>> Я ведь не зря выбрал именно этот алгоритм. Конечно я уже видел
 MP>> откомпилированный вариант, и написал аналог. Hачнем с анализа
 MP>> этого шита с ассемблерной точки зрения. Итак у нас используется
 MP>> несколько локальных переменных и регистров:
 MP>> r5-count,r6-idx,r7-dat,dptr-chartab
 AM> dptr - такая же локальная переменная, как и аккумулятор.
Hо не для асма. По сути и R0 использовать низя.
[...]
 MP>> Помнишь твой тезис о количестве локальных переменных в алгоритме?
 MP>> Вот тебе живой пример - там где в С их 4 в асме их HОЛЬ!
 AM> Они все в регистрах, то есть реально память в области RAM под них не
 AM> выделяется.
Hу на то он и пример ;) Hасколько ты понимаешь мне не составит труда накатать
алгоритм для которого мне с лихвой хватит набора из 8 текущих регистров а си
будет резервировать память под локальные переменные или глупо пушить в стек.
Конечно на больших алгоритмах не будет 4-х кратного превосходства, но засрать
весь банк и зарезервировать 16 байт си легко сможет.
 MP>> Я даже затрудняюсь посчитать оверхед по ним в таком раскладе в %,
 MP>> 0 и 4 - это какая-то бесконечность получается. ;)
 AM> Hе надо считать, оверхеда нет, переменные упали в регистры.
А кто сказал что они свободны? Ты же сам мне расказывал как хорошо на асме в
регистрах хранить всякое разное. ;)
 MP>> Дальше код - его 34 байта. Таким образом оверхед cей (причем
 MP>> современного компилятора)
 AM> Hе то, чтобы современного, этой версии уже  лет 5 наверное.
 AM> Может, кто откомпилирует на Кейл 7.хх - у меня его нет.
 MP>> составил 55.8% на абсолютно реальной embedded процедуре -
 AM> Hо утверждалось - 10 раз, то есть на порядок - 1000%, итого, ты
 AM> изначально наврал в 1000/55.8 = ~18 раз.
при усложнении процедуры (например работа с несколькими таблицами) оверхед по
коду будет прирастать с большей скоростью, по ram - с меньшей. Hу порядка не
будет но за 100% может легко.

 MP>> Да это не 2 раза но все-же цифра очень велика.
 AM> В 1.5, на мелком конкртеном примере.
 AM> Утверждалось 1.3 - на реальных проектах. Это очень недалеко от истины.
 AM> Хочешь, давай возьмем пример побольше.
Окей. Только реальный, порты, биты, таблицы, кстати у тебя есть скажем
формировалка DTMF на Си? ;)
 AM> А кто сказал, что быстрое написание на Си обусловлдено меньшим
 AM> количеством необходимых нажатий клавиш?
Hу как-бы обычно принято козырять тем, что за 1 строку си делает много всякого
полезного..
 AM>  Andy
  WBR!  Maxim Polyanskiy.


Re: Hу сейчас я вам урок грамотного программирования даду ;)
Hello Maxim,


 AM>> dptr - такая же локальная переменная, как и аккумулятор.
MP> Hо не для асма. По сути и R0 использовать низя.

А переменные запоминать в эфире..., или в космосе....

MP> [...]
 MP>>> Помнишь твой тезис о количестве локальных переменных в алгоритме?
 MP>>> Вот тебе живой пример - там где в С их 4 в асме их HОЛЬ!
 AM>> Они все в регистрах, то есть реально память в области RAM под них не
 AM>> выделяется.

MP> Hу на то он и пример ;) Hасколько ты понимаешь мне не составит труда накатать
MP> алгоритм для которого мне с лихвой хватит набора из 8 текущих регистров

Я тебе уже один раз писал, ты проигнорировал письмо. Я повторюсь.
---
Во первых, регистров может не хватить для всех локальных переменных, и
обычно не хватает.
We've slightly trimmed the long signature. Click to see the full one.
Re: Hу сейчас я вам урок грамотного программирования даду ;)
Hello Maxim,

  87          /* Индексы в буфере */
  88          unsigned char data  tx_idx   = 0;
  89          unsigned char data  save_idx = 0;
  90          /* Размер буфера должен быть степенью 2!*/
  91          unsigned char idata tx_buffer[32];
  92          
  93          void UART_Int (void) interrupt 4 using 1
  94          {
  95   1        if (_testbit_(TI)) {
  96   2          tx_idx++; /* Отметка переданного символа */
  97   2          tx_idx &= sizeof(tx_buffer) - 1; /* Закольцовка буфера */
  98   2          if (tx_idx != save_idx) {     /* Если еще есть символы */
  99   3            SBUF = tx_buffer[tx_idx];     /* Передача следующего */
 100   3          }
 101   2        }
 102   1      }
 103          
 104          void put_char_in_tx_buffer(char ch)
 105          {
 106   1        ES = 0;
 107   1        if (save_idx == tx_idx) { /* В буфере нет непереданных символов
*/
 108   2          SBUF = ch; /* Сразу начало передачи */
 109   2        }
 110   1        tx_buffer[save_idx++] = ch;  /* Запись непереданного символа */
 111   1        save_idx &= sizeof(tx_buffer) - 1;     /* Закольцовка буфера */
 112   1      
 113   1        if (save_idx == tx_idx) {             /* Переполнение буфера */
 114   2          tx_idx++;                   /* Самый старый символ потерян */
 115   2          tx_idx &= sizeof(tx_buffer) - 1;     /* Закольцовка буфера */
 116   2        }
 117   1        ES = 1;
 118   1      }
 119          
 120          
             ; FUNCTION UART_Int (BEGIN)
0000 C0E0          PUSH    ACC
0002 C0D0          PUSH    PSW
0004 75D008        MOV     PSW,#08H
                                           ; SOURCE LINE # 93
                                           ; SOURCE LINE # 95
0007 109902        JBC     TI,?C0008
000A 8013          SJMP    ?C0003
000C         ?C0008:
                                           ; SOURCE LINE # 96
000C 0500    R     INC     tx_idx
                                           ; SOURCE LINE # 97
000E 53001F  R     ANL     tx_idx,#01FH
                                           ; SOURCE LINE # 98
0011 E500    R     MOV     A,tx_idx
0013 6500    R     XRL     A,save_idx
0015 6008          JZ      ?C0003
                                           ; SOURCE LINE # 99
0017 7400    R     MOV     A,#tx_buffer
0019 2500    R     ADD     A,tx_idx
001B F8            MOV     R0,A
001C E6            MOV     A,@R0
001D F599          MOV     SBUF,A
                                           ; SOURCE LINE # 100
                                           ; SOURCE LINE # 101
                                           ; SOURCE LINE # 102
001F         ?C0003:
001F D0D0          POP     PSW
0021 D0E0          POP     ACC
0023 32            RETI    
             ; FUNCTION UART_Int (END)

             ; FUNCTION _put_char_in_tx_buffer (BEGIN)
;---- Variable 'ch' assigned to Register 'R7' ----
                                           ; SOURCE LINE # 104
                                           ; SOURCE LINE # 105
                                           ; SOURCE LINE # 106
0000 C2AC          CLR     ES
                                           ; SOURCE LINE # 107
0002 E500    R     MOV     A,save_idx
0004 B50002  R     CJNE    A,tx_idx,?C0004
                                           ; SOURCE LINE # 108
0007 8F99          MOV     SBUF,R7
                                           ; SOURCE LINE # 109
0009         ?C0004:
                                           ; SOURCE LINE # 110
0009 AE00    R     MOV     R6,save_idx
000B 0500    R     INC     save_idx
000D 7400    R     MOV     A,#tx_buffer
000F 2E            ADD     A,R6
0010 F8            MOV     R0,A
0011 A607          MOV     @R0,AR7
                                           ; SOURCE LINE # 111
0013 53001F  R     ANL     save_idx,#01FH
                                           ; SOURCE LINE # 113
0016 E500    R     MOV     A,save_idx
0018 B50005  R     CJNE    A,tx_idx,?C0005
                                           ; SOURCE LINE # 114
001B 0500    R     INC     tx_idx
                                           ; SOURCE LINE # 115
001D 53001F  R     ANL     tx_idx,#01FH
                                           ; SOURCE LINE # 116
0020         ?C0005:
                                           ; SOURCE LINE # 117
0020 D2AC          SETB    ES
                                           ; SOURCE LINE # 118
0022 22            RET    
             ; FUNCTION _put_char_in_tx_buffer (END)

MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =     74    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =      2    ----
   IDATA SIZE       =     32    ----
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.

--
С уважением,
 Andy



We've slightly trimmed the long signature. Click to see the full one.
Re: Hу сейчас я вам урок грамотного программирования даду ;)
  
  Hi!

Maxim Polyanskiy  сообщил/сообщила в новостях следующее:

Quoted text here. Click to load it

   Ну, у меня есть формировалка DTMF на С, причем на разных платформах,
так что непонятно, почему это вызывает ухмылку.
   Исторически, первый вариант был в проекте на С166. В том проекте
ресурсов было дофига, поэтому на чистом С, во всем проекте только
одна строка на асм. И та - теплый старт (jmp 0), поскольку не придумал я,
как такое на нативном С сделать.
  Другой проект - ATMega16, там было желание напихать функциональности по
максимуму, сколько будет позволять быстродействие, поэтому некоторые
критичные по времени куски  переписаны  на асме в процессе оптимизации.
Как раз кусочек из генерации DTMF (строк 15) туда попал и некоторые
обработчики прерываний
  И последний, относительно недавний вариант - на PIC16. Там основным
критерием было время разработки, поэтому опять - чистый С, ни строки на
асм.
  Во всех случаях генерация DTMF - не более пары процентов от объема
кода всего проекта (если не считать таблицу).
  То, что можно это все переписать асм, и при этом код будет чуток
покороче, сомнений не вызывает. Но сокращение все равно даже близко
не позволит упихать это в кристал меньшего размера. Процентов 20, ну 25
(по всему проекту) А во втором случае, полагаю, не будет и 20, поскольку
все, что можно оптимизировать, там уже оптимизировано.
  Поэтому нафига?

  Примите уверения в совершеннейшем к Вам почтении



Re: Hу сейчас я вам урок грамотного программирования даду ;)
Quoted text here. Click to load it

void (* jump0)(void) = (void *)0;

jump0();

Re: Hу сейчас я вам урок грамотного программирования даду ;)
3-Feb-04 18:29 Sergey Zabelin wrote to Maxim Polyanskiy:

SZ> ресурсов было дофига, поэтому на чистом С, во всем проекте только
SZ> одна строка на асм. И та - теплый старт (jmp 0), поскольку не придумал
SZ> я, как такое на нативном С сделать.

Не jmp, а call, но в данном случае это неважно, всё равно указатель
стека переинициализируется.
Может не работать только если есть защита памяти
и сегмент стека исчерпан :-)

typedef void (*voidfunc)();

void foo(char ch) {
  if (ch == 'R')
    ((voidfunc)0)();
}

wbr,

--
/* Oleksandr Redchuk, Brovary, Ukraine */
/* real '\x40' real '\x2E' kiev '\x2E' ua     */


Re: Hу сейчас я вам урок грамотного программирования даду ;)
  

"Oleksandr Redchuk" сообщил в новостях следующее:

Quoted text here. Click to load it


  Не уверен, что такое с С166 прокатит. Там же сегментный доступ
к памяти, и старшие два бита в слове - номер сегментного регистра
DPP0...DPP3. Я сейчас уже не помню, на что там DPP0 в компиляторе
показывает, но не факт, что на нулевой сегмент.
  Хотя насильно привести абсолютный адрес к указателю на
функцию - эта мысль мне в голову почему-то не приходила :-) Я стараюсь
подобные конструкции не использовать, из суеверных соображений :-)

  Примите уверения в совершеннейшем к Вам почтении




Re: Hу сейчас я вам урок грамотного программирования даду ;)
3-Feb-04 22:44 Sergey Zabelin wrote to Oleksandr Redchuk:

Quoted text here. Click to load it

SZ>   Не уверен, что такое с С166 прокатит. Там же сегментный доступ
SZ> к памяти, и старшие два бита в слове - номер сегментного регистра
SZ> DPP0...DPP3. Я сейчас уже не помню, на что там DPP0 в компиляторе
SZ> показывает, но не факт, что на нулевой сегмент.
Я 166-й вскользь смотрел очень давно, про эти 2 бита помню, но некоторые
другие вещи - нет.
Значит надо объявить эту voidfunc как far или как там у него.
Чтобы или длинный call подставило (неужели нет такого?) или сегментный
регистр перезагрузило. Раз он вообще может вызывать функции
за пределами 64K, то и это пройдёт.

SZ>   Хотя насильно привести абсолютный адрес к указателю на
SZ> функцию - эта мысль мне в голову почему-то не приходила :-) Я стараюсь
SZ> подобные конструкции не использовать, из суеверных соображений :-)
 Тёплый рестарт через jmp 0 - это уже вещь требующая аккуратности.
Раз не было сброса - значит надо ручками все регистры прописать
в нужное состояние не надеясь на умолчательные значения.
На этом фоне в одном единственном месте привести константу
к указателю окружив это громкими комментариями - можно.

wbr,
--
/* Oleksandr Redchuk, Brovary, Ukraine */
/* real '\x40' real '\x2E' kiev '\x2E' ua     */


Re: Hу сейчас я вам урок грамотного программирования даду ;)
    Hello, Andy!

Чет Янв 29 2004, Andy Mozzhevilov писал к Maxim Polyanskiy по  поводу "Re: Hу
сейчас я вам урок грамотного программирования даду ;)."
 MP>> Hу на то он и пример ;) Hасколько ты понимаешь мне не составит
 MP>> труда накатать алгоритм для которого мне с лихвой хватит набора из
 MP>> 8 текущих регистров
 AM> Я тебе уже один раз писал, ты проигнорировал письмо. Я повторюсь.
 AM> Во первых, регистров может не хватить для всех локальных переменных, и
 AM> обычно не хватает.
Вот глобальные различия - мне обычно хватает.
 AM> Во вторых, если твоя функция вызывает другую функцию, то перед
 AM> вызовом регистры нужно сохранить, чтобы не потерять значения в них,
 AM> то есть потребность в памяти никуда не девается.
Зачем сохранять - не нужно сохранять.
 AM> Либо должно быть соглашение о вызовах, например функция может портить
 AM> регистры R4,R5, а другие регистры не должна портить,
Именно - вот сдесь ты на 100% в точку!
 AM> что эквивалентно либо необходимости сохранения/восстановления этих
 AM> регистров (если вдруг функция захочет их поюзать), либо размещению
 AM> локальных переменных в памяти.
Соглашение на то и придумано чтоб функция не хотела их юзать, а главное
соглашение распространяется не на эту функцию only а на ВСЮ ПРОГУ ЦЕЛИКОМ!
 AM> Потребность в ОЗУ никуда не девается, просто немного смещаются
 AM> акценты. При вложенных вызовах кто-то должен заботится о сохранении
 AM> регистров, и сохраняются они в ОЗУ, независимо от Си/asm. - -+-
Твоя проблема в том, что ты ты пишешь о соглашении но в реале ты его просто не
можешь себе представить программы написаные таким образом, поэтому всегда
съезжаешь на сохранения.
 AM> Если рассматривать конечную функцию - лист на дереве вызовов, то
 AM> можно все переменные засунуть в регистры и ты действительно на асм
 AM> можешь получить этот локальный выигрыш, когда Си распределит какие-то
 AM> переменные в ОЗУ. Hо, может для тебя это и будет новостью, обычно
 AM> программы имеют некоторый уровень вложенности функций. В реальных
 AM> проектах малой/средней сложности на 8ми битных uC легко возможно
 AM> 5-8 вложений. В больших проектах - гораздо больше. Все твои
 AM> рассуждения относятся к последней функции, которая никого не
 AM> вызывает и обладает в полной мере всеми регистровыми ресурсами
 AM> процессора.

Ох уж мне это ООП.

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

 AM> Если будешь двигаться дальше к корню дерева вызовов, то тебе
 AM> необходимо будет заботиться о соглашении вызовов, отслеживать
 AM> используемые/неиспользуемые регистры, ручками, и в конечном итоге
 AM> производить выделение того же озу или опять же "глупо пушить в стек".
В конечном этоге этих пушей будет 1-2 в глобальных подпрограммах.
 MP>> а си будет резервировать память под локальные переменные или глупо
 MP>> пушить в стек.
 AM> Будет по мере необходимости, но не групо. Создастся компилированный
 AM> стек и переменные на разных ветвях дерева вызовов окажутся в одной и
 AM> той же ячейке ОЗУ.
Сам факт резервирования глуп. 4-5 байтовых локальных переменных это обычно все,
что надо для счастья в асмовой проге x51.
 MP>> Конечно на больших алгоритмах не будет 4-х кратного превосходства,
 MP>> но засрать весь банк и зарезервировать 16 байт си легко сможет.
 AM> Ты слышал о Си только краем уха, и не тебе рассуждать, что он может
 AM> засрать. Твой пример доказал, что Си не зарезервировал ни одного байта
 AM> ОЗУ, поскольку были доступны регистры. А на больших алгоритмах ты
 AM> будешь пользоваться ватманом размером с комнату, чтобы распределить
 AM> регистры.
не буду.
 AM>>> Hе надо считать, оверхеда нет, переменные упали в регистры.
 MP>> А кто сказал что они свободны? Ты же сам мне расказывал как хорошо
 MP>> на асме в регистрах хранить всякое разное. ;)
 AM> Приведи цитату, где я так сказал. Hе можешь?
Hу может не ты...
 MP>> при усложнении процедуры (например работа с несколькими таблицами)
 MP>> оверхед по коду будет прирастать с большей скоростью, по ram - с
 MP>> меньшей. Hу порядка не будет но за 100% может легко.
 AM> Hе надо юлить, ты дал пример, я откомпилировал оверхед 55%, ты
 AM> уже поднял его легко до 100%, на словах.
Хочешь на деле? Да возьми функцию где будет преобразование с 5-тью таблицами, и
ты получишь 5 ПАР указателей в регистрах - локальных переменных, которые засрут
озу и будут перегружатся в DPTR при каждом необходимом случае. Вот тебе оверхед
100%. Подобные кстати функции не из раздела фантастики, они легко
обнаруживаются в книжке "applied cryptography" в исходниках на твоем любимом
си, хотя в embedded они пока все-же за хвост притянуты примерно как и NRiC.
 AM>  Всегда можно найти частный случай, где оверхед Си будет больше
 AM> среднестатистического Тем не менее мифического порядка, и даже 2-ух
 AM> раз ты не показал. Что и требовалось доказать. Все твои зацепки - это
 AM> уже агония.
Смысл мне тут агонизировать. Агонизировать надо кое кому другому когда
кончается озу ;)
 AM> Hо на сей раз выбор за мной. Пример тоже очень небольшой.
 AM> Я взял из реального проекта пример передачи символов в
 AM> последовательный порт через кольцевой буфер. Пример следующим письмом.
 AM> Он не очень большой, но абсолюьно реальный.
Делать не буду но там будет как раз 15%, можешь орать, что победил ;).
 AM>>> А кто сказал, что быстрое написание на Си обусловлдено меньшим
 AM>>> количеством необходимых нажатий клавиш?
 MP>> Hу как-бы обычно принято козырять тем, что за 1 строку си делает
 MP>> много всякого полезного..

 AM> Принято говорить, что на Си
 AM> A = B + С;
 AM> Выглядит более читаемо и сопровождаемо, чем на asm

 AM> MOV dptr,#Addr_B
 AM> MOV A,@dptr
 AM> MOV R7,A
 AM> MOV dptr,#Addr_C
 AM> MOV A,@dptr
 AM> ADD A,R7
 AM> MOV Addr_A,A
Это не на асм - это вопервых неработоспособно а во вторых смахивает на
производное компиляторов ЯВУ ;)
 AM> С уважением,
 AM>  Andy
  WBR!  Maxim Polyanskiy.


Re: Hу сейчас я вам урок грамотного программирования даду ;)
Hello Maxim,

 MP>>> Hу на то он и пример ;) Hасколько ты понимаешь мне не составит
 MP>>> труда накатать алгоритм для которого мне с лихвой хватит набора из
 MP>>> 8 текущих регистров

 AM>> Я тебе уже один раз писал, ты проигнорировал письмо. Я повторюсь.
 AM>> Во первых, регистров может не хватить для всех локальных переменных, и
 AM>> обычно не хватает.
MP> Вот глобальные различия - мне обычно хватает.

8 регистров х51 для всех вложений ?
И сколько у тебя их, вложений? 2? Тогда понятно.

 AM>> Во вторых, если твоя функция вызывает другую функцию, то перед
 AM>> вызовом регистры нужно сохранить, чтобы не потерять значения в них,
 AM>> то есть потребность в памяти никуда не девается.
MP> Зачем сохранять - не нужно сохранять.

Переменные могут понадобиться и после вызова функции.

 AM>> Либо должно быть соглашение о вызовах, например функция может портить
 AM>> регистры R4,R5, а другие регистры не должна портить,
MP> Именно - вот сдесь ты на 100% в точку!

 AM>> что эквивалентно либо необходимости сохранения/восстановления этих
 AM>> регистров (если вдруг функция захочет их поюзать), либо размещению
 AM>> локальных переменных в памяти.
MP> Соглашение на то и придумано чтоб функция не хотела их юзать, а главное
MP> соглашение распространяется не на эту функцию only а на ВСЮ ПРОГУ ЦЕЛИКОМ!

Если в функции нужно 10 локальных переменных, что будешь делать?
Скажешь, что задача не имеет решения и откажешься от работы?
Или все таки положишь часть локальных в ОЗУ?

 AM>> Потребность в ОЗУ никуда не девается, просто немного смещаются
 AM>> акценты. При вложенных вызовах кто-то должен заботится о сохранении
 AM>> регистров, и сохраняются они в ОЗУ, независимо от Си/asm. - -+-
MP> Твоя проблема в том, что ты ты

Не волнуйся так, заикаться уже начал :)

MP> пишешь о соглашении но в реале ты его просто не можешь себе представить
MP> программы написаные таким образом,

Могу, и ты это продемонстрировал. Но есть предел такой эффективности.
2-3 вложенных вызова функций и она кончилась. А главное - что особо она
никому и не нужна. Только для самолюбования.

MP> поэтому всегда съезжаешь на сохранения.

Приведи пример такого соглашения, которое позволит при необходимсоти
10 локальных переменных и 2-ух аргументов функции не использовать
более, чем 8 регистров х51. Причем не обязательно все параметры 8-ми
битные.

 AM>> проектах малой/средней сложности на 8ми битных uC легко возможно
 AM>> 5-8 вложений. В больших проектах - гораздо больше. Все твои
 AM>> рассуждения относятся к последней функции, которая никого не
 AM>> вызывает и обладает в полной мере всеми регистровыми ресурсами
 AM>> процессора.

MP> Ох уж мне это ООП.

Причем здесь вообще ООП?

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

MP> опору отливать из бетона.

А у тебя значит основной цикл без вложенных вызовов, все едино и
монолитно.

 AM>> Если будешь двигаться дальше к корню дерева вызовов, то тебе
 AM>> необходимо будет заботиться о соглашении вызовов, отслеживать
 AM>> используемые/неиспользуемые регистры, ручками, и в конечном итоге
 AM>> производить выделение того же озу или опять же "глупо пушить в стек".
MP> В конечном этоге этих пушей будет 1-2 в глобальных подпрограммах.

Это от объема задачи зависит.

 MP>>> а си будет резервировать память под локальные переменные или глупо
 MP>>> пушить в стек.
 AM>> Будет по мере необходимости, но не групо. Создастся компилированный
 AM>> стек и переменные на разных ветвях дерева вызовов окажутся в одной и
 AM>> той же ячейке ОЗУ.
MP> Сам факт резервирования глуп. 4-5 байтовых локальных переменных это обычно
все,

MP> что надо для счастья в асмовой проге x51.

Потому что ты видимо не писал сложных проектов, а писал мелкие
драйвера типа обслуживания i2c и дисплея. Какой объем кода, без
таблиц, в своих проектах под х51? Или опиши функциональность своих
устройств, чтобы понять о какой сложности идет речь.

 AM>>>> Hе надо считать, оверхеда нет, переменные упали в регистры.
 MP>>> А кто сказал что они свободны? Ты же сам мне расказывал как хорошо
 MP>>> на асме в регистрах хранить всякое разное. ;)
 AM>> Приведи цитату, где я так сказал. Hе можешь?
MP> Hу может не ты...

Ну может в следующий раз и подумаешь, прежде чем трепаться.

 MP>>> при усложнении процедуры (например работа с несколькими таблицами)
 MP>>> оверхед по коду будет прирастать с большей скоростью, по ram - с
 MP>>> меньшей. Hу порядка не будет но за 100% может легко.
 AM>> Hе надо юлить, ты дал пример, я откомпилировал оверхед 55%, ты
 AM>> уже поднял его легко до 100%, на словах.
MP> Хочешь на деле? Да возьми функцию где будет преобразование с 5-тью
таблицами, и

MP> ты получишь 5 ПАР указателей в регистрах - локальных переменных,

Вообще, таблицы - это не столь распространенные вещи. Да, они есть,
бывают, но они не обрабатываются в каждой функции проекта. И долеко не
в каждом проекте их есть больше 2-ух, а тем боляя 5. А фактически,
скорее всего будет использован только dptr, и никакого резервирования
не будет. Резервируются объявленные переменные, а не те, что нужны для
промежуточных вычислений адресов.

 AM>>  Всегда можно найти частный случай, где оверхед Си будет больше
 AM>> среднестатистического Тем не менее мифического порядка, и даже 2-ух
 AM>> раз ты не показал. Что и требовалось доказать. Все твои зацепки - это
 AM>> уже агония.

MP> Смысл мне тут агонизировать. Агонизировать надо кое кому другому когда
MP> кончается озу ;)

У меня еще ни разу не кончалось.

 AM>> Hо на сей раз выбор за мной. Пример тоже очень небольшой.
 AM>> Я взял из реального проекта пример передачи символов в
 AM>> последовательный порт через кольцевой буфер. Пример следующим письмом.
 AM>> Он не очень большой, но абсолюьно реальный.
MP> Делать не буду но там будет как раз 15%, можешь орать, что победил ;).

Что-ж так? Это же реальный код.
То есть признаем, что перерасход ПЗУ на Си от 15 до 50% в зависимости
от конкртеного проекта? Перестаем голословно говорить о мифических порядках
и разы? Я правильно понял?
Только я не победил, а доказал, с инструментом в руках. Чего и вам
всегда желаю делать.

 AM>> Принято говорить, что на Си
 AM>> A = B + С;
 AM>> Выглядит более читаемо и сопровождаемо, чем на asm

 AM>> MOV dptr,#Addr_B
 AM>> MOV A,@dptr
 AM>> MOV R7,A
 AM>> MOV dptr,#Addr_C
 AM>> MOV A,@dptr
 AM>> ADD A,R7
 AM>> MOV Addr_A,A

MP> Это не на асм -

А на чем?

MP> это вопервых неработоспособно

Почему? Ну может в синтаксисе напутал немного.

MP> а во вторых смахивает на производное компиляторов ЯВУ ;)

А как будет правильно на асм?
Сложить 2 байта из xdata и поместить результат в data.

--
С уважением,
 Andy



We've slightly trimmed the long signature. Click to see the full one.
Re: Hу сейчас я вам урок грамотного программирования даду ;)
Hello, Maxim!
You wrote to Andy Mozzhevilov on Fri, 30 Jan 2004 01:03:03 +0300:

 MP> Ох уж мне это ООП.

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

    А при чём тут ООП? Мне довелось "пропахать носом" асмовские исходники
достаточно сложной и большой библиотеки. Занималось оно EGA графикой, а я
оттуда выколупывал знания о том как это самое EGA устроено. Крутая была
новинка по тем временам. Эхх, молодой я был, горячий :-)). Так вот там,
доложу тебе, соглашения о связях очень жёстко выполнялись. Для меня это было
вновинку - если мы не собираемся вызывать эту подпрограмму из С и даже не
начинаем её имя с подчёркивания - зачем такие строгости? Потом понял...

Alexander,Derazhne@adic,kiev,ua (replace commas with dots)
Alexander Derazhne



Re: Hу сейчас я вам урок грамотного программирования даду ;)
Hемедленно нажми на RESET, Maxim Polyanskiy!


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

   Ряд алгоритмов из бетона отлить весьма затруднительно...

 AM>> ОЗУ, поскольку были доступны регистры. А на больших алгоритмах ты
 AM>> будешь пользоваться ватманом размером с комнату, чтобы распределить
 AM>> регистры.
 MP> не буду.

   Если снизу писать. Hо тогда в написанном ничего поменять нельзя:
компилятор за тебя с ватманом работает при каждой перекомпиляции,
а ты один раз -- при написании функций-листьев дерева вызовов.

 AM>> Hе надо юлить, ты дал пример, я откомпилировал оверхед 55%, ты
 AM>> уже поднял его легко до 100%, на словах.
 MP> Хочешь на деле? Да возьми функцию где будет преобразование с 5-тью
 MP> таблицами, и
 MP> ты получишь 5 ПАР указателей в регистрах - локальных переменных, которые
 MP> засрут
 MP> озу и будут перегружатся в DPTR при каждом необходимом случае. Вот тебе
 MP> оверхед

   А на ассемблере обращение по указателю будет осуществляться
магическим образом?



Hу сейчас я вам урок грамотного программирования даду ;)
    Hello, Kirill!

Вcк Фев 01 2004, Kirill Frolov писал к Maxim Polyanskiy по поводу "Re: Hу
сейчас я вам урок грамотного программирования даду ;)."
 MP>> Хочешь на деле? Да возьми функцию где будет преобразование с
 MP>> 5-тью таблицами, и ты получишь 5 ПАР указателей в регистрах -
 MP>> локальных переменных, которые засрут озу и будут перегружатся в
 MP>> DPTR при каждом необходимом случае. Вот тебе оверхед
 KF>    А на ассемблере обращение по указателю будет осуществляться
 KF> магическим образом?
Да. Как общатся с таблицами до 256 байт комайндой movc a,@a+pc я уже показывал.

  WBR!  Maxim Polyanskiy.


Re: Hу сейчас я вам урок грамотного программирования даду ;)
Hемедленно нажми на RESET, Maxim Polyanskiy!


 MP>>> локальных переменных, которые засрут озу и будут перегружатся в
 MP>>> DPTR при каждом необходимом случае. Вот тебе оверхед
 KF>>    А на ассемблере обращение по указателю будет осуществляться
 KF>> магическим образом?
 MP> Да. Как общатся с таблицами до 256 байт комайндой movc a,@a+pc я уже
 MP> показывал.

   В данном случае указатель сохраняется в PC. Где чёрная магия?


Site Timeline