реклама на сайте
подробности

 
 
> bootloader в WinAVR, к вопросу оптимизации
MaxiMuz
сообщение Jun 25 2011, 16:58
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Простая программка:
Код
************************************************
ПРИМЕР МИГАНИЯ СВЕТОДИОДАМИ
************************************************
#include <avr/io.h>

int main(void)
{
PORTB |=_BV(PB2) | _BV(PB0);
DDRB |= _BV(PB0);
while (1) {
if (bit_is_clear(PINB,PB2)) PORTB |= _BV(PB0);
else PORTB &= ~_BV(PB0);
}
}

Использовал различные уровни оптимизации (OPT = s в данном случае)
Команда: "make.exe" all выдает следующий протокол:
Код
Creating load file for Flash: test.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature test.elf test.hex

Creating load file for EEPROM: test.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex test.elf test.eep || exit 0

Creating Extended Listing: test.lss
avr-objdump -h -S -z test.elf > test.lss

Creating Symbol Table: test.sym
avr-nm -n test.elf > test.sym

Size after:
AVR Memory Usage
----------------
Device: attiny2313

Program: 114 bytes (5.6% Full)
(.text + .data + .bootloader)

Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)



-------- end --------


> Process Exit Code: 0
> Time Taken: 00:02


Получается вот такой код:
Код
test.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000072  00000000  00000000  00000054  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .debug_aranges 00000020  00000000  00000000  000000c6  2**0
                  CONTENTS, READONLY, DEBUGGING
  2 .debug_pubnames 0000001b  00000000  00000000  000000e6  2**0
                  CONTENTS, READONLY, DEBUGGING
  3 .debug_info   00000076  00000000  00000000  00000101  2**0
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_abbrev 00000041  00000000  00000000  00000177  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_line   00000073  00000000  00000000  000001b8  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_frame  00000020  00000000  00000000  0000022c  2**2
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_str    00000079  00000000  00000000  0000024c  2**0
                  CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:

00000000 <__vectors>:
   0:    12 c0           rjmp    .+36; 0x26 <__ctors_end>
   2:    2a c0           rjmp    .+84; 0x58 <__bad_interrupt>
   4:    29 c0           rjmp    .+82; 0x58 <__bad_interrupt>
   6:    28 c0           rjmp    .+80; 0x58 <__bad_interrupt>
   8:    27 c0           rjmp    .+78; 0x58 <__bad_interrupt>
   a:    26 c0           rjmp    .+76; 0x58 <__bad_interrupt>
   c:    25 c0           rjmp    .+74; 0x58 <__bad_interrupt>
   e:    24 c0           rjmp    .+72; 0x58 <__bad_interrupt>
  10:    23 c0           rjmp    .+70; 0x58 <__bad_interrupt>
  12:    22 c0           rjmp    .+68; 0x58 <__bad_interrupt>
  14:    21 c0           rjmp    .+66; 0x58 <__bad_interrupt>
  16:    20 c0           rjmp    .+64; 0x58 <__bad_interrupt>
  18:    1f c0           rjmp    .+62; 0x58 <__bad_interrupt>
  1a:    1e c0           rjmp    .+60; 0x58 <__bad_interrupt>
  1c:    1d c0           rjmp    .+58; 0x58 <__bad_interrupt>
  1e:    1c c0           rjmp    .+56; 0x58 <__bad_interrupt>
  20:    1b c0           rjmp    .+54; 0x58 <__bad_interrupt>
  22:    1a c0           rjmp    .+52; 0x58 <__bad_interrupt>
  24:    19 c0           rjmp    .+50; 0x58 <__bad_interrupt>

00000026 <__ctors_end>:
  26:    11 24           eor    r1, r1
  28:    1f be           out    0x3f, r1; 63
  2a:    cf ed           ldi    r28, 0xDF; 223
  2c:    cd bf           out    0x3d, r28; 61

0000002e <__do_copy_data>:
  2e:    10 e0           ldi    r17, 0x00; 0
  30:    a0 e6           ldi    r26, 0x60; 96
  32:    b0 e0           ldi    r27, 0x00; 0
  34:    e2 e7           ldi    r30, 0x72; 114
  36:    f0 e0           ldi    r31, 0x00; 0
  38:    02 c0           rjmp    .+4    ; 0x3e <.do_copy_data_start>

0000003a <.do_copy_data_loop>:
  3a:    05 90           lpm    r0, Z+
  3c:    0d 92           st    X+, r0

0000003e <.do_copy_data_start>:
  3e:    a0 36           cpi    r26, 0x60; 96
  40:    b1 07           cpc    r27, r17
  42:    d9 f7           brne    .-10; 0x3a <.do_copy_data_loop>

00000044 <__do_clear_bss>:
  44:    10 e0           ldi    r17, 0x00; 0
  46:    a0 e6           ldi    r26, 0x60; 96
  48:    b0 e0           ldi    r27, 0x00; 0
  4a:    01 c0           rjmp    .+2    ; 0x4e <.do_clear_bss_start>

0000004c <.do_clear_bss_loop>:
  4c:    1d 92           st    X+, r1

0000004e <.do_clear_bss_start>:
  4e:    a0 36           cpi    r26, 0x60; 96
  50:    b1 07           cpc    r27, r17
  52:    e1 f7           brne    .-8    ; 0x4c <.do_clear_bss_loop>
  54:    02 d0           rcall    .+4    ; 0x5a <main>
  56:    0b c0           rjmp    .+22; 0x6e <_exit>

00000058 <__bad_interrupt>:
  58:    d3 cf           rjmp    .-90; 0x0 <__vectors>

0000005a <main>:
  5a:    88 b3           in    r24, 0x18; 24
  5c:    85 60           ori    r24, 0x05; 5
  5e:    88 bb           out    0x18, r24; 24
  60:    b8 9a           sbi    0x17, 0; 23
  62:    b2 99           sbic    0x16, 2; 22
  64:    02 c0           rjmp    .+4    ; 0x6a <main+0x10>
  66:    c0 9a           sbi    0x18, 0; 24
  68:    fc cf           rjmp    .-8    ; 0x62 <main+0x8>
  6a:    c0 98           cbi    0x18, 0; 24
  6c:    fa cf           rjmp    .-12; 0x62 <main+0x8>

0000006e <_exit>:
  6e:    f8 94           cli

00000070 <__stop_program>:
  70:    ff cf           rjmp    .-2    ; 0x70 <__stop_program>

Собственно полезный код занимает десяток байт , таблица векторов прерваний - это понятно, далее секция <__ctors_end>:
первые две команды - обнуление SREG ! Для каких это целей ?
Оставшийся код как я понимаю bootloader ?
зачем он тут нужен ?
Как исключить его из кода ?

Сообщение отредактировал MaxiMuz - Jun 25 2011, 17:02
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 20)
_Артём_
сообщение Jun 25 2011, 18:06
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата
Оставшийся код как я понимаю bootloader ?
зачем он тут нужен ?


Неправильно понимаете: Bootloader в AVR - область во flash. содержащая программу самопрограммирования (обновления версии прошивки)
Go to the top of the page
 
+Quote Post
ataradov
сообщение Jun 25 2011, 18:19
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 014
Регистрация: 8-01-07
Из: San Jose, CA
Пользователь №: 24 202



Оставшийся код - это то, что позволяет неинициализированным глобальным переменным иметь 0 знаение, как и положено по стандарту Си.
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Jun 25 2011, 20:38
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(Taradov Alexander @ Jun 25 2011, 21:19) *
Оставшийся код - это то, что позволяет неинициализированным глобальным переменным иметь 0 знаение, как и положено по стандарту Си.

я подозревал это sm.gif ну а как это выключить ?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 25 2011, 20:49
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (MaxiMuz @ Jun 25 2011, 22:38) *
я подозревал это sm.gif ну а как это выключить ?

Это можно, только ответьте сначала на два вопроса:
1) Вы находясь в здравом уме собираетесь работать с неициализированными переменными с произвольным значением?
2) Если нет, то не стоит-ли Вам подумать, что инициализация их по одной займет больше кода, нежели оптом?

P.S.
На форуме есть раздел для начинающих. И не стоит по каждому чиху создавать новую тему, тем более не подобающих разделах.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Jun 26 2011, 06:48
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(zltigo @ Jun 25 2011, 23:49) *
P.S.
На форуме есть раздел для начинающих. И не стоит по каждому чиху создавать новую тему, тем более не подобающих разделах.

Чем же этот раздел не подобает ? Других я не нашел
А на вопрос вы не ответили !
Go to the top of the page
 
+Quote Post
ataradov
сообщение Jun 26 2011, 08:24
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 014
Регистрация: 8-01-07
Из: San Jose, CA
Пользователь №: 24 202



QUOTE (MaxiMuz @ Jun 26 2011, 10:48) *
А на вопрос вы не ответили !

С помощью линерного скрипта можно выкинуть все что угодно, читайте документацию на ld и правьте стандартный скрипт.

PS: Только помните, что весь остальной код компилятор будет делать рассчитывая на то, что этот код присутствует, удачи в поимке странных и трудноуловимых багов.

Сообщение отредактировал Taradov Alexander - Jun 26 2011, 08:26
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 26 2011, 08:38
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (MaxiMuz @ Jun 26 2011, 08:48) *
Других я не нашел

Не верю, просто обычная привычка гадить, где попало sad.gif, не читать ни документации на компилятор, ни пользоваться знаниями накопленными на форуме.
QUOTE
А на вопрос вы не ответили !

Моим условием ответа на вопрос был для начала ответ на два моих вопроса - тоже типа "не нашли" sad.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
XVR
сообщение Jun 27 2011, 08:51
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



То, что вы видели называется Statrup. Он написан на ассемблере и присутствует в виде сорца в библиотеке (crt0.s или что то похожее). Его можно заменить из скрипта линкера.
Пишите свой и подменяйте sm.gif
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Jun 27 2011, 15:59
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(zltigo @ Jun 25 2011, 23:49) *
Это можно, только ответьте сначала на два вопроса:
1) Вы находясь в здравом уме собираетесь работать с неициализированными переменными с произвольным значением?
2) Если нет, то не стоит-ли Вам подумать, что инициализация их по одной займет больше кода, нежели оптом?

Непонимаю смысл инициализации все области памяти , если я с ней не работаю
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jun 27 2011, 16:40
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(MaxiMuz @ Jun 27 2011, 19:59) *
Непонимаю смысл инициализации все области памяти , если я с ней не работаю
В Вашем случае (примере) никакой инициализации и не производится: фактически производится проверка, что инициализация не нужна (точнее, что инициализировать нужно 0 слов памяти). Реальные программы, обычно, гораздо сложнее Вашего примера, и, обычно, без инициализации некоторых областей памяти не обойтись. Если что-то в стандартном startup'е Вас не устраивает, то можно его поправить...
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Jun 28 2011, 07:17
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(Палыч @ Jun 27 2011, 19:40) *
... Если что-то в стандартном startup'е Вас не устраивает, то можно его поправить...

можно - это хорошо ! каким образом ?
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Jun 28 2011, 10:30
Сообщение #13


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



Цитата(MaxiMuz @ Jun 28 2011, 11:17) *
можно - это хорошо ! каким образом ?

У вас контроллер имеет 128 байт памяти? Или ради принципа?
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Jun 29 2011, 06:56
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(jorikdima @ Jun 28 2011, 13:30) *
У вас контроллер имеет 128 байт памяти? Или ради принципа?

К примеру взять ATtiny2313 контроллер имеет 2кБ памяти программ , а фактически 1кБ слов (команд). И часто случается что каждый байт на счету. Поэтому 128 байт - тоже обьем, и принцып тут ни причем
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jun 30 2011, 05:45
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Цитата
Поэтому 128 байт - тоже обьем, и принцып тут ни причем


Тогда надо учится писать на AVR-ассемблере, или брать контроллер подходящий по объему флеша к реализуемой задаче
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 30 2011, 05:50
Сообщение #16


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (MaxiMuz @ Jun 29 2011, 09:56) *
И часто случается что каждый байт на счету. Поэтому 128 байт - тоже обьем, и принцып тут ни причем
У вас такое бывало? Вероятнее всего - нет. Ибо ужать 2К программу на 128 байт обычно не составляет труда. Дальнейшая дискуссия неинтересна - вы спорите о вкусе устриц с теми, кто их ел.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
MaxiMuz
сообщение Jul 2 2011, 06:06
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658



Цитата(Сергей Борщ @ Jun 30 2011, 08:50) *
У вас такое бывало? Вероятнее всего - нет. Ибо ужать 2К программу на 128 байт обычно не составляет труда. Дальнейшая дискуссия неинтересна - вы спорите о вкусе устриц с теми, кто их ел.

У меня в ближайшем будущем стоит задача ужать хотябы на 100Б код для АТтини2313 ... Прога писана в Ассеблере, изначально уже оптимизирована и по обьему кода и по скорости. В случае написании на Си и оптимизации по обьему (Оs), код , я думаю , тоже будет ужат нормально, а этих 128Б может как раз не хватить
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 5 2011, 00:22
Сообщение #18


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата
В случае написании на Си и оптимизации по обьему (Оs), код , я думаю , тоже будет ужат нормально, а этих 128Б может как раз не хватить

не понимаю я bootloader'ы в WinAVR, CV, ICC или еще какой-то байде, для бутсекций в 2kb. Если старая программа написана на asm'е да еще и соптимизирована, то на Си вы просто ни при каких обстоятельствах не сможете добиться такого функционала в том же объеме, не говоря уже о расширении оного.

Функционал который со скрипом влезет в самую большую бут секцию (2kb) с макс оптимизацией на WinAVR, - на асм поместится в самую маленькую бутсекцию из 256 байт. Достигается это за счет оптимальных прологов/эпилогов функций и исключительно регистровых переменных.
Реализция бутлоадера на Сях оправдана разве только "тайм ту маркетом" либо большим объемом флеш целевого МК. На С vs ASM, вы всегда потеряете или функциональность, или объем, или скорость, или всё сразу, какой бы ключик оптимизации не ставили.

Цитата(Сергей Борщ @ Jun 30 2011, 08:50) *
У вас такое бывало?
Ибо ужать 2К программу на 128 байт обычно не составляет труда. Дальнейшая дискуссия неинтересна - вы спорите о вкусе устриц с теми, кто их ел.

У меня вот что есть сказать, - бутсекция 1кб - поддержка: modbus по 485-му, загрузка с внешней eeprom'ки, CRC апп секции, шифрование в обе стороны... Портирование между МК байты приходится искать вставляя код в неиспользуемые ячейки таблицы векторов, проект собирается ровно в 1024байт ни одной свободной ячейки флеш (портировать с m8 напр на m16 - занятие не особо веселое, и найти там не то что 128, 8 байт без урезания функционала - большая проблема). Зато освобождается целый 1кб под апликейшин, для 8/16кб флешевых чипов - очень актуально. Бутлоадер - это такой тип программы, где простота найти 128 байт - означает недодать эти 128 байт (чаще больше) аппликейшину, а там они явно нужнее.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 5 2011, 09:03
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (defunct @ Jul 5 2011, 03:22) *
Функционал который со скрипом влезет в самую большую бут секцию (2kb) с макс оптимизацией на WinAVR, - на асм поместится в самую маленькую бутсекцию из 256 байт. Достигается это за счет оптимальных прологов/эпилогов функций и исключительно регистровых переменных.

Как человек неоднократно писавший загрузчики размером от 128байт до 16килобайт, как на ASM, так и на С для самых разных контроллеров, не могу не сказать, что соотношение 256 и 2048 есть абсолютный бред. Для получения такого "результата" нужно писать даже не левой ногой, а протезом левой ноги и после многократной лоботомии. На прикладных программах в десятки килобайт, ситуация с ASM становится еще печальнее, если программа создается за конечное время.
QUOTE
какой бы ключик оптимизации не ставили.

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

QUOTE (defunct @ Jul 5 2011, 03:22) *
не понимаю я bootloader'ы в WinAVR, CV, ICC или еще какой-то байде, для бутсекций в 2kb.

Совершенно достаточный размер для более,чем многофункционального загрузчика. Все, что больше 1K редко способно выдержать конкуренцию с C. Ниша ASM загрузчиков заканчивается на уровне 128...256, максимум 512 байт. Дальше в 99% совершенно бессмысленно, даже при наличии хорошего опыта и больших шишек в ASM-описании. Результат-же большинства писателей на ASM (читай тех, кто только уровень ASM сумел понять и принять) вообще начинает не лезть в никакие ворота sad.gif. Вышесказанное, естественно, совершенно не означает того, что любой освоивший copy-paste мусора из интернету и прочитавший книгу типа Редькинской способен вообще что-то вменяемое написать на C. Тут порог вхождения в качественное программирование повыше будет.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 5 2011, 12:59
Сообщение #20


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(zltigo @ Jul 5 2011, 12:03) *
Для получения такого "результата" нужно писать даже не левой ногой, а протезом левой ноги и после многократной лоботомии. На прикладных программах в десятки килобайт, ситуация с ASM становится еще печальнее, если программа создается за конечное время.

Достаточно одного неаккуратного оператора "*", "/" чтобы занять 2KB в 8-ми битнике.
Речь не о прикладных программах. Bootloader имеет самое постоянное и самое длительное время жизни. Требует высокой скорости работы, компактности и функционала.

То что там состряпает winavr и есть код писанный протезом левой ноги.

Цитата
Совершенно достаточный размер для более,чем многофункционального загрузчика.

При условии что есть возможность поместить тот же функционал в 1KB, тратить 2KB неразумно.

Цитата
Все, что больше 1K редко способно выдержать конкуренцию с C.

загрузчик по TFTP через ethernet на asm укладывается в 2KB секцию.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 5 2011, 13:22
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (defunct @ Jul 5 2011, 15:59) *
Bootloader имеет самое постоянное и самое длительное время жизни. Требует высокой скорости работы,

Скорость работы ему требуется в последнюю очередь, ибо работает он редко, в идеале никогда.
QUOTE
компактности и функционала.

Компактность и функционал должны быть достаточными, а не самоцелью.
QUOTE
То что там состряпает winavr и есть код писанный протезом левой ноги.

То, что Вы назвали winavr, есть GCC. Не самый плохой компилятор. Делает то, что ему прикажут. Для AVR, правда, есть и получше.
QUOTE
При условии что есть возможность поместить тот же функционал в 1KB, тратить 2KB неразумно.

Повторяю, cегодня, а не в середине 80x, на уровне программ размером 1-2K выигрыша в два раза между ASM и профессионально написанным C не бывает.
Двухкратным превосходством можете изредка себя тешить на кусочках программ с единицы-десятки байт.
QUOTE
загрузчик по TFTP через ethernet на asm укладывается в 2KB секцию.

TFTP/UDP/IP как раз тот случай когда смысл использования ASM равен ровно нулю. Проверено неоднократно. Та-же поддержка сети в на рубеже 80/90х писалась для своей операционки на 286 на ASM. На ASM тогда писалось все по причине того, что 12MHz 286 был отнюдь не гигант производительности и экономился каждый такт в системе жесткого реального времени с эмулятором виртуальной машины. Всякие фокусы, типа модифицируемого на лету кода тоже приходилось использовать. Доступные тогда C компиляторы были совершенно сырыми sad.gif. Эта фигня, как ни странно, живет и немного сопровождается по сей день. Не переписана на C по двум причинам - там все-таки набежало более 120K кода, что по любому немалая работа, и в общем-то это уже лет 10 минимум развивать бессмысленно.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 22:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01584 секунд с 7
ELECTRONIX ©2004-2016