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

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

Translate This Thread From Russian to

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

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

MP> rotorman.nm.ru/18H.ZIP

И что, ты мне предлагаешь изучить исходник аона в более 10000 строк на
ассемблере абсолютно без каких-либо без комментариев?
Да еще на странной помеси диалекта intel8080 с Z80?
Хотя впрочем быстрый просмотр показывает, что иногда
аргументы передаются через глобальные переменные в том числе:
        RES     1,(IX+SOFLG1)
        CALL    KEYCHECK
...
PACK60: MVI     L,60
        MVI     (IX+67),0
        CALL    PACK2

Где они там используются особо у меня времени разбираться нет.

И ты утверждаешь, что это сопровождаемо кем-либо, кроме автора?

И ты хочешь сказать, что даже сам автор смог бы сопровождать это,
скажем сейчас, через 5-10 лет?

Кстати, там используются индексные регистры, тебя это не смущает?
Как-то ты утверждал, что использование индексных регистров в Z80
видел один раз после разбора результата компилятора с ЯВУ.
Здесь индексные регистры используются. Что следует под этим понимать:
1. Что ты врал?
2. Что эта программа - как раз та программа, изначально написаная на
   ЯВУ, а потом просто дизассемблирована прошивка :)?

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



We've slightly trimmed the long signature. Click to see the full one.
Re: Hу сейчас я вам урок грамотного программирования даду ;)
Mon Feb 02 2004 15:03, Andy Mozzhevilov wrote to Maxim Polyanskiy:

 MP>> Я тебе исходник 10-ти летней давности один выложил - посмотри.
 MP>> rotorman.nm.ru/18H.ZIP

 AM> И что, ты мне предлагаешь изучить исходник аона в более 10000 строк на
 AM> ассемблере абсолютно без каких-либо без комментариев?
 AM> Да еще на странной помеси диалекта intel8080 с Z80?
 AM> ...
 AM> Здесь индексные регистры используются. Что следует под этим понимать:
 AM> 1. Что ты врал?
 AM> 2. Что эта программа - как раз та программа, изначально написаная на
 AM>    ЯВУ, а потом просто дизассемблирована прошивка :)?

То, что прошивка дизассемблирована, а не является исходником,
видно хотя бы по названиям меток.

WBR, Юрий.


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

31 Jan 04 00:04, you wrote to Andy Mozzhevilov:

 AM>> Если в функции нужно 10 локальных переменных, что будешь делать?
 MP> Если функции нужно 10 локальных переменных - программер ламер и скорее
 MP> всего половина из них (а то и все) должны быть глобальными! Алгоритмы
 MP> с 10-тью указателями и счетчиками цикла - бредятина свойственная ЯВУ.


 AM>> Скажешь, что задача не имеет решения и откажешься от работы?
 AM>> Или все таки положишь часть локальных в ОЗУ?
 MP> Даже не задумаюсь над этим.

 MP> Да предельная глубина стека асмовой проги вызовов 5-8, иначе надо
 MP> че-то править в консерватории. А в реале вложенность еще меньше.

 MP>>> В конечном этоге этих пушей будет 1-2 в глобальных
 MP>>> подпрограммах.

 MP> В последнее время стараюсь влезать в 8-16к.

 MP> Hе знаю. Я тебе уже говорил - не реальный пример класть БАЙТ в xram!
 MP> Потому, что для них есть ram, а если ты кладешь байт в xram - значит
 MP> ram твой любимый язык уже засрал.

 MP> Правильно в XDATA БАЙТЫ не раскладывать!

По моему, я тебя понял. Ты не делаешь задачи, которые не вписываются в твои
ограничения.

Alexey


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

28 Jan 04 01:50, you wrote to Andy Mozzhevilov:

 MP> откомпилированный вариант, и написал аналог. Hачнем с анализа этого шита с
 MP> ассемблерной точки зрения. Итак у нас используется несколько локальных
 MP> переменных и регистров: r5-count,r6-idx,r7-dat,dptr-chartab
 MP>......

 MP> Дальше код - его 34 байта. Таким образом оверхед cей (причем современного
 MP> компилятора) составил 55.8% на абсолютно реальной embedded процедуре -
 MP> обслуге индикатора, а ни какие-то там мифические 10-15-30%. Да это не 2
 MP> раза но все-же цифра очень велика.

   В общем случае необходимо исходить из гипотезы, что подпрограмма
  будет вызываться из другой подпрограммы, которая написана в аналогичном
  стиле, то-есть с использованием тех же регистров. Следовательно добавь
  код: push,pop  - это еще  10 команд, или строчек...




Alexey


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

   Andy, ты ещё здесь сидишь?


Пятница Январь 30 2004 07:39, Andy Mozzhevilov wrote to Maxim Polyanskiy:

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

 Кстати, комментарий по теме. Hормальный программист после изучения
принципов ООП во многих ассемблерных программах может очень активно
использовать таблицы - они существенно сокращают код и заметно
облегчают проектирование и сопровождение. 5 и больше таблиц - типичная
величина в большинстве моих программ, написанных за последние годы...





                                                   Георгий


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

Wed Jan 28 2004 01:50, Maxim Polyanskiy wrote to Andy Mozzhevilov:

 MP> Это уже 2-е доказательство того, что даже по ТЕКСТУ ИСХОДHИКА cи имеет
 MP> ОВЕРХЕД, а хваленое быстрое написание на деле является мифом ;)

"Быстрое написание" касается вещей громоздких, больших программ с высокой
связностью.  Маленький же и эффективный алгоритм, конечно, на ассемблер ложится
хорошо.


Dimmy.


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

   Alexander, ты ещё здесь сидишь?


Суббота Январь 31 2004 16:25, Alexander Derazhne wrote to Maxim Polyanskiy:

 AD>     Hачиная с некоторого уровня начинают сказываться некие эффекты, с
 AD> которыми ты до сих пор не сталкивался. Они действительно не заметны в
 AD> маленьких и манипусеньких проектах. В более крупных они начинают
 AD> вылезать на первый план. Это называют "размерным эффектом", "законом
 AD> перехода количества в качество" и т.д. Попытки преодолеть их
 AD> очевидными и логичными мерами не приводят к желаемому результату.

 Приводят. Как только для программиста становятся очевидными и логичными
вполен понятные приёмы грамотного программирования.

 AD> Собственно, все нововведенения, вроде "модульного", "структурного",
 AD> объектного" и прочих "программирований" направленны на преодоление
 AD> этих эффектов.

 И эти _принципы_ можно изуметельно применять при программировании
на ассемблере, успешно преодолевая "проблемы роста" проекта.

 AD>  Объяснить их суть я тебе не смогу, это нужно испытать
 AD> на своей шкуре.

 Суть можно в книжках прочитать. А вот преимущества такого подхода,
действительно, лучше всего испытать "на своей шкуре" ;-)




                                                   Георгий


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.


Site Timeline