PDA

Просмотр полной версии : Библиотеки-модули-программы...



Страницы : [1] 2

Vitamin
10.10.2006, 22:13
Захотелось мне тут помечтать. Вот и размечтался.... :)

Перелопачивал тут намедни в очередной раз свою библиотеку модулей, попутно одним глазом посматривая в разные доки на тему независимых релоцируемых модулей для разных платформ. И представил себе такую ниибаццо(С) вдохновляющую картину.
Каждый спектрумист имеет у себя некий системный диск. На него свалены самые нужные в повседневной жизни программы- коммандеры, редакторы, прочий хлам. Обычно нужного софта там скапливается порядком- иногда и на целый диск получается. А ведь, если разобраться, большая часть кода всех утилит состоит из пользовательского интерфейса, дискового функционала, какого-то графического движка.
А теперь представим себе системный диск, на котором находится несколько десятков бейсик-файлов размером от 3 до 10 секторов и кучка библиотек, используемых в разном сочетании разными программами. (Ясен перец, в случае винта и единой ФС это выглядит вообще вкусно). Бейсик-файл содержит загрузчик уникального для каждой программы кодового блока, распаковщик (в общем случае), список используемых библиотек и линковщик. После запуска загрузчик распаковывает в память кодовый блок, ищет, распаковывает и линкует к нему найденные модули и запускает все это дело.
Понятно, что при таком подходе будут как плюсы, так и минусы. Начну с первых:
+ экономия дискового пространства (не всегда, но в общем случае)
+ простота исправления одного глюка в ряде программ (и соотвецно добавления новых глюков %)))
+ разработчикам можно меньше заморачиваться- главное иметь библиотеку, ее интерфейс и работать с ней
Пока хватит, можно к минусам перейти:
- много (и долго!) придется елозить по диску пока соберутся нужные библиотеки, а потом слинкуются
- куча мелких файлов может и займут мало места, но быстро забьют каталог
- трудности с переносом и копированием программ
- возможные проблемы с совместимостью- разные версии, разные интерфейсы...
Тоже пока хватит.
Теперь можно указать некоторые пути удаления минусов.
1) сжимать библиотеки пакерами. Благо там внутри довольно много "лишней" информации может быть
2) собирать набор библиотек в архив и искать уже в нем (уже не говорю о кешировании каталога для быстрого поиска)
3) утилита автосборщик, собирающая из загрузчика и кучки библиотек единый упакованный моноблок, запускаемый на любой машине, решает третий минус :)

Вот, в принципе, все. На самом деле, минусов и плюсов куда больше, чем я тут указал.
Что скажет многоуважаемый All?

jim
10.10.2006, 22:24
дело нужное. я так же мыслю. давно пора унифицировать спексофт. 21 век на дворе.

Jukov
11.10.2006, 07:37
Я пытался сделать библиотеку как раз для этого дела, чтоб были скрол бары, менюшки, мышь, удобный вывод текста, в котором присутсвуют все символы ГОСТ-альтернативной кодировки. Всё это вылилось в одной программе - CUTTER. Дело застопорилось на дисковых процедурах. Идею использовать одну библиотеку для всех системных программ одназначно поддерживаю.

captain cobalt
11.10.2006, 09:04
Ещё можно выходить из программы не по RESET, а в ось. При этом библиотеки остаются в памяти. При запуске следущей программы не нужно опять подкачивать библиотеки, достаточно загрузить программу и слинковать её с библиотеками в памяти.

Vitamin
11.10.2006, 09:20
Ещё можно выходить из программы не по RESET, а в ось. При этом библиотеки остаются в памяти. При запуске следущей программы не нужно опять подкачивать библиотеки, достаточно загрузить программу и слинковать её с библиотеками в памяти.
Библиотеки под ось и библиотеки в описанном выше виде- разные вещи. Для обычной программы требуется определенный набор библиотек, лишних не надо- на них просто нет памяти. Тем более что после стартовой линковки они уже не пригодны для дальнейшего использования в другой библиотеке- они будут настроены на конкретный адрес.
Ну вдобавок можно реализовать API для runtime-линковки модулей.

captain cobalt
11.10.2006, 11:09
Библиотеки под ось и библиотеки в описанном выше виде- разные вещи. Тем не менее, следует хотя бы рассмотреть возможность брать библиотеки не с диска, а из памяти.

Для обычной программы требуется определенный набор библиотек Ещё есть хорошая и полезная штука - плагины.
Их набор заранее неизвестен и может настраиваться пользователем.

лишних не надо- на них просто нет памяти Это у 128 может не хватит.
А у 256 и тем более 512 и выше запросто может хватить не только на все библиотеки, но и на несколько программ, чтобы запускать их из памяти.

Не следует рассуждать о 128-only.

Тем более что после стартовой линковки они уже не пригодны для дальнейшего использования в другой библиотеке- они будут настроены на конкретный адрес. Непонятно.
Библиотека сидит в памяти, настроенная на адрес.
Ну и пусть там сидит.
Это её вновь загружаемых клиентов надо линковать с учётом этого адреса.

CityAceE
11.10.2006, 11:17
А вот здесь (http://zx.pk.ru/showthread.php?t=1912&page=1&pp=10) я не про то же говорил?

Wlodek
11.10.2006, 11:55
Если я отдам все исходники в формате GENS3/GENS4, без комментариев или с комментариями матом, это новых программистов устроит?
Готов.
Сам уже ничего не помню, прошло около 15 лет.
Извиняюсь.

Vitamin
11.10.2006, 15:04
А вот здесь я не про то же говорил?
О том же. Но с точки зрения исходников. Здесь же разговор идет о бинарных библиотеках.
"Конструктор" из исходников- первый шаг к этому. Имея на руках только бинарник и список точек входа исчезает проблема ковыряния и разбирания что и как работает (и соотвецно исчезают соблазны доделать все под себя).

acidrain
11.10.2006, 15:16
О том же. Но с точки зрения исходников. Здесь же разговор идет о бинарных библиотеках.
"Конструктор" из исходников- первый шаг к этому. Имея на руках только бинарник и список точек входа исчезает проблема ковыряния и разбирания что и как работает (и соотвецно исчезают соблазны доделать все под себя).
Именно об этом я и говорил 100 лет назад. Shaos даже сделал многое в плане реализации данной мысли. Правда для спринтера, но применимо и для спека. За основу только не берите пц и линух вид либл. Используйте амижные. опъяснять не пуду пачаму=)))
А про либлы от Shaos'a - спросите у него на его форуме http://www.nedopc.org/forum/

yoko_ono
11.10.2006, 15:25
Именно об этом я и говорил 100 лет назад. Shaos даже сделал многое в плане реализации данной мысли. Правда для спринтера, но применимо и для спека. За основу только не берите пц и линух вид либл. Используйте амижные. опъяснять не пуду пачаму=)))
А про либлы от Shaos'a - спросите у него на его форуме http://www.nedopc.org/forum/

Куда уж им амижные-то за образец брать, они ж её никогда в глаза не видели... =) пц (линух и винда) 'разъел моск'... :(

icebear
11.10.2006, 16:03
Куда уж им амижные-то за образец брать, они ж её никогда в глаза не видели... =) пц (линух и винда) 'разъел моск'... :(

А что в них, либах амижных, особенного? И почему миллионы леммингов и в этом случае ошиблись?

Vitamin
11.10.2006, 16:43
Куда уж им амижные-то за образец брать, они ж её никогда в глаза не видели... =) пц (линух и винда) 'разъел моск'...
Хехе. А если сказать "(от)куда уж вам qnx'овые (linux'овые, bsd'шные etc) бинарники брать, вы ж его никогда в глаза не видели... =) амига 'съела моск, даже костный, напихала вместо него опилок, нацепила дурацкую улыбку и отправила работать продавцом в магазины Евросети' ;)

А если по теме. Структура модулей, например, для Linux (ELF) поддерживает множество типов данных, что весьма хорошо для библиотек, создаваемых на ЯВУ (if any...). Поддерживает ли это пресловутые hunks?

acidrain
11.10.2006, 18:20
А что в них, либах амижных, особенного? И почему миллионы леммингов и в этом случае ошиблись?
Ошиблись. =) А особенность в том, что они не так сделаны и не ресурсоемкие и для работы им не надо много тонн памяти, как в других случаях.
Цитата: А если по теме. Структура модулей, например, для Linux (ELF) поддерживает множество типов данных, что весьма хорошо для библиотек, создаваемых на ЯВУ (if any...). Поддерживает ли это пресловутые hunks?
Хммм. я собственно не знаю про типы данных описываемых и поддерживаемых в эльфах, но и смысла не вижу. Все типы данных на амиге, если вы не в курсе, поддерживает система datatypes. Кстати, до сих пор многие оси черпают из этой системы плюсы. Про яву не знаю что и как =(
Вы бы сначала изучили что такое амижные либлы и с чем их едят.
For info: http://www.nedopc.org/forum/viewtopic.php?t=7689&highlight=lib
http://www.nedopc.org/nedopc/shaos/libman_r.shtml

Vitamin
11.10.2006, 19:58
Вы бы сначала изучили что такое амижные либлы и с чем их едят.
For info: http://www.nedopc.org/forum/viewtop...9&highlight=lib
http://www.nedopc.org/nedopc/shaos/libman_r.shtml
Почитал. Познавательно. А теперь несколько технических вопросов
1) По первой ссылке описание заголовка библиотеки, по второй пример, не соответствующий описанию структуры. Это два разных формата? Если да, то где описание на второй формат

Далее разговор про первый (описанный) формат
2) Релоцируемость модуля присутствует (технических подробностей не увидел правда, было бы интересно, киньте ссылкой, если есть), зачем нужен выбор желаемого окна?
3) Керналь в виде точек входа- не есть гут, по крайней мере для той цели, которую я описал первым постом ветки. Вместо этого должна быть линковка с коррекцией кода вызывающего модуля для подстановки конкретных адресов вызова (а также структур данных)

По поводу второй ссылки. Поддержки релоцируемости не замечено. Я прав?

yoko_ono
11.10.2006, 22:45
Почитал. Познавательно. А теперь несколько технических вопросов
1) По первой ссылке описание заголовка библиотеки, по второй пример, не соответствующий описанию структуры. Это два разных формата? Если да, то где описание на второй формат

Уважаемый acidrain, видимо, погорячился, или же я чего-то не поняла. По ссылкам что-то, имеющее отношение к спринтеру.



Далее разговор про первый (описанный) формат
2) Релоцируемость модуля присутствует (технических подробностей не увидел правда, было бы интересно, киньте ссылкой, если есть), зачем нужен выбор желаемого окна?

На амиге либа - тот же ехешник, и так же фиксится под абсолютные адреса при загрузке.



3) Керналь в виде точек входа- не есть гут, по крайней мере для той цели, которую я описал первым постом ветки. Вместо этого должна быть линковка с коррекцией кода вызывающего модуля для подстановки конкретных адресов вызова (а также структур данных)

То есть вы утверждаете, что корректировать каждую левую программу под абсолютные адреса библиотеки - лучше, чем давать каждой программе лишь адрес начала точек входа на либу? Тем самым наглядно демонстрируется тезиc 'пц выел моск'...
Программы на амиге могут быть СОВЕРШЕННО релоцируемые, без данных релокации вообще, и при этом замечательно пользоваться любыми либами.

С единственным исключением - на Z80 нет команды call (ix+const)

bugsy
11.10.2006, 22:49
...Тем самым наглядно демонстрируется тезиc 'пц выел моск'...

жжошь Лена!!!

yoko_ono
11.10.2006, 22:55
На мой скромный взгляд, изначальная идея уважаемого Vitamin'a продиктована больше подражательством пц, нежели реальной необходимостью и удобством.
Как он правильно заметил, линковка с некими либами в рунтайме (в момент запуска программы) приведёт к коматозу. Причём, не побоюсь этого слова, к жуткому коматозу. Гораздо быстрее будет прочитать 'статически слинкованный' (пользуясь пцшными терминами) кодовый блок, который к тому же и зажмётся лучше, чем много отдельных кусочков. Идея либ ещё как-то жизнеспособна в рамках некой ОСи (уровня хотя бы издоса), да и то уж никак не с линковкой в момент запуска заново каждой программы.

Vitamin
11.10.2006, 23:00
Читать внимательно. Вторая ссылка - там про релокацию есть. а перва - это типа кто то пишет оську для шпринтера. и по второй ссылке вопросы Shaos'у.
Попутался. Читал ссылки в обратном порядке, поэтому... :)
В таком случае что такое перемещающаяся таблица? Каково ее назначение, формат, особенности?


А во вторых - линковка - это уже вында
А еще под Linux есть линковщик (ld, gcc). Это тоже винда?????? :)))


То есть вы утверждаете, что корректировать каждую левую программу под абсолютные адреса библиотеки - лучше, чем давать каждой программе лишь адрес начала точек входа на либу?
Читаем тему с начала. Грузим стартовый кодовый блок (который может быть нерелоцируемым), а к нему уже клеим (и настраиваем на адрес) необходимые библиотеки, подставляя нужные адреса в точки вызова.


Программы на амиге могут быть СОВЕРШЕННО релоцируемые, без данных релокации вообще, и при этом замечательно пользоваться любыми либами.
В огороде бузина, а в Киеве дядька. На х86 тоже всяких команд полно, а на АРМ тоже дофига. А вот 8051 по сравнению с зетником вообще убожество, а ведь дофига чего на нем слабать можно! Так что не путайте кислое с длинным. Здесь разговор о спектруме и тех возможностях других платформ, которые можно подсмотреть и использовать. И команда

call (ix+const)
к их числу не относится.

ЗЫ. А я думал что Амига- добрый такой компьютер... Оказывается тоже моск съела у некоторых граждан...

Vitamin
11.10.2006, 23:07
На мой скромный взгляд, изначальная идея уважаемого Vitamin'a продиктована больше подражательством пц, нежели реальной необходимостью и удобством.
Если разобраться, то все кому-то подражают. Автора первых "стрелочек и окошек" в каком-нибудь буте или коммандере тоже небось с пеной у рта обвиняли в подражательстве Xerox/Apple или (страшным шепотом) ВИНДЕ!!! И ничего, это не мешало резво топтать клавиши и рулить стрелкой, а потом высунув язык присобачивать мышу.
При том уровне развития ПО для разработки, которое имеем сейчас, идея весьма сыра (использование кросс-ассемблеров не подразумевается).


Как он правильно заметил, линковка с некими либами в рунтайме (в момент запуска программы) приведёт к коматозу. Причём, не побоюсь этого слова, к жуткому коматозу.
Не такой уж и жуткий. Основные потери на загрузку/распаковку файлов. Линковка (особенно если используются символические имена) тоже ресурсоемка (но меньше, чем дисковые операции), а вот настройка на адреса весьма быстра.


Гораздо быстрее будет прочитать 'статически слинкованный' (пользуясь пцшными терминами) кодовый блок, который к тому же и зажмётся лучше, чем много отдельных кусочков.
Ну вот сейчас везде сплошь и рядом такое и есть- грузится моноблок, за ним статически слинкованный и упакованный кусок кода. На кону мочало, начинай сначала...
Смысл идеи- вынести общие куски кода в отдельные файлы (части файла в случае архива библиотек). Если пользователь готов поступиться временем загрузки программы в угоду универсальности и обновляемости- пожалуйста, не готов- лепим моноблоки и получаем что хотели

acidrain
11.10.2006, 23:10
к сожалению на инглише только - http://www.mways.co.uk/amiga/howtocode/text/generalguidelines.php
пока в поисках еще линков на аутодоки...

Vitamin
11.10.2006, 23:19
Не перекручивай, ты понял я о чем. а линковка в том виде как есть на линухе и проч. есть на любой машине, где есть нормальный Си.
Честно? не понял. Что такого специфичного в линковке у винды, чего нет больше нигде?

Vitamin
11.10.2006, 23:36
Зачем идти через зад, когда можно через парадный вход?
Пошли :) Будем плясать от печки, думаю недопонимания уменьшится.
Имеем два подхода к проблеме линковки:
1) Загрузчик подгружает необходимые библиотеки, линкует их между собой и главной программой, настраивает адреса и стартует главную программу. С ее точки зрения, она состоит из сплошного куска кода/данных- как обычная спектрумовская программа.
2) Главная программа должна подключить использованные библиотеки. При этом они
а) грузятся в хвост главной программы и настраиваются. В итоге получаем то же что и в 1)
или
б) грузятся в заранее определенное место, настраиваются и вызываются уже там. Ограничивает свободу распределения памяти.

Так? Или я что-то упустил?

acidrain
11.10.2006, 23:37
Я б с удовольствием дал нормальные ссылки на нужные описания, но они под (с) и так сходу в нете их не найти.
Посему токо всякая чепуха и поподается...
http://wandel.ca/homepage/execdis/devices_doc.txt

Vitamin
11.10.2006, 23:58
Что линковать?
Блин... Линковка- это связь нескольких кусков кода для совместной работы. В первом случае (моем методе) это делается путем непосредственного слияния кусков кода. Во втором случае (твоем, амижном, виндовом и т.д. методе) случае это делается путем получения хендла и вызова функций. Линковка (в любом виде) исключается только в случае если "все свое ношу с собой" и больше ничего не надо.

acidrain
12.10.2006, 00:13
Vitamin, чего тебе эта линковка далась?
Что ты линкуешь, если твоя прога даже не подозревает о том, как либла функцию выполняет? Прога делает лишь вызов подпрограммы, ждет результа (подтверждения) и продолжает дальше. Может там вообще будет ret вместо подпрограммы. Зачем линковать твою прогу к моей либле, если сидит себе резидентом (например) либла graphix.library в банке №н. Прога лишь делает запрос к основной либле (ехес) (скажем, с бейсиком грузится) об открытии либлы графикс, затем пользует ее нафсю.
Потом прога закрылась, а либла осталась, если скажем не было bc,gfx_handle; de,flushlibrary; hl,execbase; jp (hl), то ее может следующая прога заюзать! Причем, заметь, БЕЗ ЛИНКОВКИ! =)

Vitamin
12.10.2006, 00:20
Причем, заметь, БЕЗ ЛИНКОВКИ! =)
Ага. А откуда эта либа взялась? Нарисовалась из воздуха? Плюс опять, где она лежит весьма важно- при статическом распределении памяти (как это обычно для ситуации без ОС) нужен полный контроль над памятью. Да и не будет следующая прога юзать эту либу! Потому как нету ОС и поддерживающих !!BEEP!! средств (раз уж тебя так ломает слышать слово "линковка" :), хотя ты описал именно ее).

acidrain
12.10.2006, 00:29
Читай:

Прога лишь делает запрос к основной либле (ехес) (скажем, с бейсиком грузится) об открытии либлы графикс, затем пользует ее нафсю.
Назвай как хочешь, пусть будет открытие либлы отныне называться линковка.
Пойми. Старые проги _не_ будут пользоваться твоими дллками (так как это не либла, а лишь пцшная дллка, тьху!), а новые проги - вполне могут знать, что банка №н - под либлы. Номер банки можно определить перед открытием и проге это надо знать. Как ты говоришь - тоже ведь не то, а вдруг начнет распаковывать куски, самомодифицироваться прога и еще вдобавок будет автокод в память мусорить. ТАДА что? Висяк? Тут уже тебе не шутки шутить ;) Это типа играть по правилам, отдаленно напоминающие оську

Vitamin
12.10.2006, 00:42
Это типа играть по правилам, отдаленно напоминающие оську
Без оськи это совершенно напрасное извращение.

Концепция "либа в банке" хороша для программ, поддерживающих плагины. В этом случае программа играет роль ОС, а плагины- роль приложений. Дает им порулить системными вызовами (без промежуточного вызова- открытия библиотеки) и т.п.
Я же говорю несколько о другом. О runtime-самосборке программ из имеющихся на диске библиотек. В этом случае не страшна и самомодификация и имеется полная власть над памятью. За это дело придется платить задержками при загрузке (или собрать все в моноблок и получить обычную программу).

ЗЫ. Изначально моя мысль стремилась к следующему- доработать мою модульную структуру до вида, применимого в некоторых моих программах. Для этого собираю информацию о способах представления объектного кода на разных платформах, пытаясь взять что-то интересное ото всех. Попутно размечтался (см. первый пост :) ). А тут налетел народ и давай расхваливать амигу (притом чисто на словах, безо всякой полезной для меня информации). Ты исключение- подкидываешь ссылки, кой-что нужное уже накопал :)

Shaos
12.10.2006, 03:24
Линк на либмана (http://www.nedopc.org/nedopc/shaos/libman_r.shtml) я пару раз упоминал на этом форуме - 0 заинтересовавшихся ;)

Если интересующихся наберется >= 3, то обещаю портировать со спринтера на спектрум - примеры либ в этом формате имеются, штука сильно перспективная была, да вот тока спринтер загнулся...

elf/2
12.10.2006, 11:19
Скажем так, керналь (exec.library на амми) ничего не литнкует! Зачем линковать? Прога запросила либлу, скажем gadgets.library - ехес ее ищет, грузит в память, возвращает ее хендл (адрес в мемори т.е. точка входа), прога уже со смещением от хендела (т.с. номер подфункции) в регистре D0 (типа А на з80) вызывает начальный адрес либлы - тама физически прописаны jp $......
моск совсем изъеден :( а чем это отличается от виндового:

HMODULE h = LoadLibrary(pluginName);
FOO fn = (FOO)GetProcAddress(h,"foo");
(*fn)();
CloseHandle(h);

или линуксового:

m = dlopen("libsample.so", RTLD_LAZY);
fn = (FOO)dlsym(m, "foo");
(*fn)();
dlclose(m);

icebear
12.10.2006, 11:35
Ошиблись. =) А особенность в том, что они не так сделаны и не ресурсоемкие и для работы им не надо много тонн памяти, как в других случаях.

Это не ответ. Я верю, что они "не так сделаны", а вот почему и как и что?


Вы бы сначала изучили что такое амижные либлы и с чем их едят.
For info: http://www.nedopc.org/forum/viewtopic.php?t=7689&highlight=lib
http://www.nedopc.org/nedopc/shaos/libman_r.shtml

А где там про амижные либы? Либо когда Спринтер успел превратится в Амигу?

Vitamin
12.10.2006, 12:12
HMODULE h = LoadLibrary(pluginName);
FOO fn = (FOO)GetProcAddress(h,"foo");
(*fn)();
CloseHandle(h);

или линуксового:

m = dlopen("libsample.so", RTLD_LAZY);
fn = (FOO)dlsym(m, "foo");
(*fn)();
dlclose(m);
Угу. Вот про это я и говорил. Те же фаберже только в профиль. Товарисчи кроме винды ничего не видели, зато вовсю гордятся тем, что видели амигу, а другие нет.

acidrain
12.10.2006, 14:24
вот чем отличается:

; /+================================================= ==========+/
; // //
; // Open all Needed Libraries and Try Optional Ones. //
; // //
;/+================================================= ==========+/
OpenLibs

;==== Exec Always needed !
move.l #EM0,Exitmessage
move.l Execbase,a6
move #39,d0 ;version
lea IntName,a1
call OpenLibrary
move.l d0,Intuibase
tst.l d0
beq .fail

;==== Dos needed for VBL task (NO MORE VBLTASK).
;==== dos always needed.
IFNE Own_Dosbase
move.l #EM1,Exitmessage
move #36,d0 ;version
lea DosName,a1
call OpenLibrary
move.l d0,_DOSBase
tst.l d0
beq .fail
ENDC
;==== ASL needed for screen request.
move.l #EM2,Exitmessage
move #36,d0 ;version
lea _AslName,a1
call OpenLibrary
move.l d0,Aslbase
tst.l d0
beq.b .fail

;==== Graphics always needed.
move.l #EM3,Exitmessage
move #39,d0 ;version
lea GraName,a1
call OpenLibrary
move.l d0,GfxBase
tst.l d0
beq.b .fail

;==== Cybergraphics.library can be here or NOT !!
;==== if d0 = 0, CGX Screens are impossible.
move #39,d0 ;version number was not checked.
lea Cgxname,a1 ;"39" must work for CGX3 and 4.
call OpenLibrary
move.l d0,Cgxbase ;can not cause error.

;===== we MUST open timer.device to synchronise the scripts.
; OpenDevice("timer.device",0L, (struct IORequest *) AudioIO ,0L);

;== alloc some iorequest

;error = OpenDevice(devName, unitNumber, iORequest, flags)
;D0 A0 D0 A1 D1

move.l #IOTV_SIZE,d0 ;size of "iorequest for timer device" structure.
jsr _AllocRmb
tst.l d0
beq.s .fail
move.l d0,TimerDev
move.l d0,a1

move.l Execbase,a6
lea Timername,a0
move.l #UNIT_MICROHZ,d0 ; It has precision down to about 2 microseconds,...
clr.l d1
call OpenDevice
move.l d0,TimerDevResult ;used for closing
tst.l d0 ; 0 if successful
beq .nodevice
clr.l d0
bra.s .yesdevice
.nodevice
moveq.l #-1,d0
.yesdevice


;Note: if CGX is not present, 0 is returned as base.
; It can be a nice way to decide if the screen will be
; AGA or CGX.
;
.ok
moveq.l #-1,d0 ;no error!!!
.fail
rts
=)
Ребятки, либо я плохой учитель либо вы аккордионисты.

acidrain
12.10.2006, 14:37
Чтоб вас не вводить в заблуждение -

; +------------------------------------------------------------+
; / /
; / Useful Macros /
; / /
;+------------------------------------------------------------+

call macro
jsr _LVO\1(a6)
endm

elf/2
12.10.2006, 15:01
вот чем отличается:

код поскипал... честно, не понял что ты этим исходником хотел сказать :(
ну на асме он, ну и что?

в винде тоже можно:
1. в рантайме загрузить библиотеку по имени и получить в какой-то регистровой паре ее handle (он не является адресом загрузки, ну и что?)
2. если вернули INVALID_HANDLE_VALUE то есть какие-то проблемы, какие именно можно узнать дернув еще одну системную функцию
3. дальше получаем указатель на функцию передав ее имя или порядковый номер (после этого они нам не нужны)
4. зовем ее по этому указателю напрямую
5. когда библиотека больше не нужна, выгружаем ее
6. если библиотека собрана без base relocation то грузиться она будет по фиксированным адресам и накладных расходов при загрузке не будет...

подозреваю что read-only сегменты (код) могут шариться между процессами, хотя утверждать этого не буду

возможно при компиляции кода получиться больше чем в предложенном примере, но если есть желание то можно и на асме написать...


Блин, совок в действии! Такого сопротивления на западе вряд ли встретишь, по личному опыту знаю.
а причем здесь совок? мне интересно понять чем именно амиговский подход к работе с либами сильно отличается от той же винды.


забыл добавить что init/cleanup тоже есть, система дергает фунцию dllMain c нужным аргументом

Vitamin
12.10.2006, 15:08
Такого сопротивления на западе вряд ли встретишь
Сопротивления ЧЕМУ? Промывке мозгов на тему того, что в амиге все сделано единственно правильным методом? Как наглядно показал elf/2, в той же винде и линухе с динамическими библиотеками работа идет ТОЧНО ТАК ЖЕ- подключили-вызвали-освободили. Это и есть динамическая линковка в runtime.

icebear
12.10.2006, 15:25
Млин, читайте, народ, не беситесь! Написал же, что я не только амигой и спеком увлечен. И для информации дал ссылки! Мне еще кому что разжевать?! Я не думал, что уважаемый мной icebear настолько невнимателен.

Дело скорее всего в тебе :) Как прикажешь понимать приведённые тобой линки сразу после твой же фразы "Вы бы сначала изучили что такое амижные либлы и с чем их едят."?


Не, ну смешно! А ты TOS видел? Давайте пиписьками меряться?

Да нет, какие пиписьки? Ты сказало, что амижные либы круче, вот народ и заинтересовался, "потянулся". А ты сразу обижаться. Написал бы понятнее, вопросов бы не возникло. Так что всё нормально :v2_cheer:


И еще, опишите процесс открытия, всезнайки наши, либл в винде и линухе. я описал, хоть и поверхностно.

Ну elf/2 написал же тебе уже.

icebear
12.10.2006, 16:49
А в том, что с моей подачи Шаос писал либман и применялся кое какой амижный опыт. Исчерпывающе?

Для того, что бы догаться о таком развитии дел, какие способности надо иметь?


Я не сказало - у меня есть пол, он МУЖСКОЙ. Не среднего рода. Я не говорил, что они круче, не приписывай.

Ну чего ты как маленький. Я ошибся в написании, не нарочно, разве это так не ясно было. И за слова не цепляйся. Круче в данном случае - "что они не так сделаны и не ресурсоемкие и для работы им не надо много тонн памяти". Нафига кипятком писать, если смысл моих слова понятен? Если уж на принцип идти - вопрос мой был к yoko_ono, а отвечать стал ты. Кто теперь виноват, что твой ответ был непонятно сформулирован?

icebear
12.10.2006, 16:51
Далее уточните. Почему тоже самое на амми менее ресурсоемкое и более шустрое (сравнивая одинаковые мощности компов)?
Зачем тогда dll на спеке мутить? Если на вашем любимом пц есть либлы? Делайте как на пц - не длл а либлы.

Не про меня, но я влезу. Параметры ресурсоёмкости и шустрости, а так же одинаковых мощностей компов (единицы измерения интересуют) в студию. И ещё, надеюсь разница между dll и lib известна?

PS: Предупреждая возможное неправильное толкование - ничего личного.

acidrain
12.10.2006, 17:00
И ещё, надеюсь разница между dll и lib известна?
Нет, просвяти!

acidrain
12.10.2006, 17:06
Цитата:
Сообщение от acidrain
Не, ну смешно! А ты TOS видел? Давайте пиписьками меряться?


Да нет, какие пиписьки? Ты сказало, что амижные либы круче, вот народ и заинтересовался, "потянулся". А ты сразу обижаться. Написал бы понятнее, вопросов бы не возникло. Так что всё нормально
Думаю ясно видно что цитата моя, значит я и ответил, причем тут йокоона? =)
Ну я не обидчивый! Даже могу признать свои промахи и минусы - стараюсь развиваться во всех отношениях 8)

acidrain
12.10.2006, 17:10
код поскипал... честно, не понял что ты этим исходником хотел сказать :(
ну на асме он, ну и что?

Асм/неасм - что под руку попалось, то и получили :) Лишь показал механизм открытия/закрытия либлы.


в винде тоже можно:
1. в рантайме загрузить библиотеку по имени и получить в какой-то регистровой паре ее handle (он не является адресом загрузки, ну и что?)
Я не пц кодер, что значит не является адресом загрузки?


2. если вернули INVALID_HANDLE_VALUE то есть какие-то проблемы, какие именно можно узнать дернув еще одну системную функцию У шайтан! Такого видимо нигде нет, если акцентировал внимание на ИНВАЛИДЕ_ДЕРЖАК_ЗНАЧЕНИЕ. АОС вернет сразу номер ошибки.


3. дальше получаем указатель на функцию передав ее имя или порядковый номер (после этого они нам не нужны)
Также практически, согласен.

4. зовем ее по этому указателю напрямую
Ага, тоже самое.

5. когда библиотека больше не нужна, выгружаем ее
На пц есть плюс - если не выгрузил лохопрограммер, то вында ввыгрузит ее сама, я прав?

6. если библиотека собрана без base relocation то грузиться она будет по фиксированным адресам и накладных расходов при загрузке не будет...Не могу представить, тк на амиге все релоцируемо, зачем статика?


подозреваю что read-only сегменты (код) могут шариться между процессами, хотя утверждать этого не будуНе совсем понял, что ты имеешь тут ввиду.


возможно при компиляции кода получиться больше чем в предложенном примере, но если есть желание то можно и на асме написать... не об этом речь.
Анализируя все вышесказанное - утверждаю - пц круче! :v2_finge: Но амми ближе и разумней. =)

elf/2
12.10.2006, 17:10
Далее уточните. Почему тоже самое на амми менее ресурсоемкое и более шустрое (сравнивая одинаковые мощности компов)?
допустим что ты прав и Windows/Linux реализация динамических библиотек жрет больше ресурсов и работает медленне (хотя как правильно заметил icebear это никто не замерял).

могу предположить что это результат того что:
1. реализация на Амми менее гибкая
2. на Амми все написано на асме и оптимизировалось ручками


Зачем тогда dll на спеке мутить? Если на вашем любимом пц есть либлы? Делайте как на пц - не длл а либлы
как я понимаю пока никто ничего не мутит. ты сказал что на амми есть уникальная реализация разделяемых библиотек, которой нигде больше нет. более того она идеально подходить для переноса на спекки. народ здесь присутсвующий это серьезно заинтересовало, захотелось (по крайней мере мне) узнать об этом побольше... все ссылки которые здесь пролетали достаточного света не пролили

и тут не обижаться надо и PC ругать, а объяснить в конструктивном русле что есть что на амми/PC/MacOS/etc.

Vitamin
12.10.2006, 17:13
Я фигею, дорогая редакция... 4 страницы (в общей сложности) наездов... Куда катится мир...

ЗЫ. Судя по вмешательству в дискуссию свежих людей, делаю вывод, что умопомешательства у меня нет. А то вчера уж грешным делом подумал, что мои ответы в теме были лишь в моем сознании, поскольку они не брались в расчет совершенно.

elf/2
12.10.2006, 17:22
Я не пц кодер, что значит не является адресом загрузки?
handle - это некий уникальный идентификатор библиотеки (32 битное число)


У шайтан! Такого видимо нигде нет, если акцентировал внимание на ИНВАЛИДЕ_ДЕРЖАК_ЗНАЧЕНИЕ. АОС вернет сразу номер ошибки.
это экономит одну-две комманды и наверное больше ничего. если вариантов ошибок много, то все равно придется делать отдельную функцию для их обработки/показа пользователю


На пц есть плюс - если не выгрузил лохопрограммер, то вында ввыгрузит ее сама, я прав?
да, когда процесс завершиться и если никто ее больше не использует


Не совсем понял, что ты имеешь тут ввиду.
если несколько процессов загрузили одну и туже библиотеку, то неизменяемые сегменты (например сегмент кода) будет присутсвовать в памяти один раз. хотя на 100% не уверен


Анализируя все вышесказанное - утверждаю - пц круче! Но амми ближе и разумней. =)
ну зачем ты так? я подозреваю что у любой платформы есть чему поучиться

icebear
12.10.2006, 17:24
Нет, просвяти!

А всё очень просто: lib - это статическая библиотека, она так же релоцируемая, но вот она "впечатывается" в конечной код программы при линковке (с правкой всех вызовов ессно). От этого растёт размер программы. Ну а dll - ты сам знаешь. Причём dll в винде загружается один раз, по первому требованию. Есть возможность загрузить dll напрямую самому (как показал elf/2), либо (как бы это сказать по-русски правильнее, прошу прощение, но русская терминология в этом случае мне почти незнакома) скомпилировать вызов какой-либо функции из нужной библиотеки, так что при исполнении этого вызова винда сама подгрузит библиотеку. Последний метод - это все окна на винде, ибо user32 и gdi32 с запуска системы висят в памяти. На Амиге это вряд ли сделано по-другому.

acidrain
12.10.2006, 17:34
Ладно, отвлеклись. Не хотел ни кого обидеть.
В моем варианте - программа запрашивает нужную либлу, основная ее ищет на винте(диске и чем угодно), грузит, возращает точку входа. далее главенствует прога - пользует либлу (несколько, если надо).
В варианте Витамина как это все будет выглядеть?

acidrain
12.10.2006, 17:36
handle - это некий уникальный идентификатор библиотеки (32 битное число)
не ответил на вопрос. имхо =)

acidrain
12.10.2006, 17:38
1. реализация на Амми менее гибкая
2. на Амми все написано на асме и оптимизировалось ручками
1 - нет
2 - нет, Си и только Си

acidrain
12.10.2006, 17:39
уникальная реализация разделяемых библиотек, которой нигде больше нет
я так не говорил! не приписывайте!

acidrain
12.10.2006, 17:41
и тут не обижаться надо и PC ругать, а объяснить в конструктивном русле что есть что на амми/PC/MacOS/etc.
Си знаешь? Читай реализацию (пример либлы). Есть вопросы - многие с удовольствием подскажут.
Шаоса так и не заметили? Он вам предложил реальное дело! Вы наплевали, давай на меня давить! Вы че, ребзя?! Давайте делать а не писдоболить!

acidrain
12.10.2006, 17:43
если несколько процессов загрузили одну и туже библиотеку, то неизменяемые сегменты (например сегмент кода) будет присутсвовать в памяти один раз. хотя на 100% не уверен
Вообще на амиге одна либла на всех она не дублируется в памяти.

acidrain
12.10.2006, 17:44
поскольку они не брались в расчет совершенно.
тоже могу сказать и в твой адрес! =)

acidrain
12.10.2006, 17:46
На Амиге это вряд ли сделано по-другому.
Либ отсутствует. Если только в Си или в т.сказать HLL...

icebear
12.10.2006, 17:51
Либ отсутствует. Если только в Си или в т.сказать HLL...

Нифиганепонял. Причём здесь язык программирования как таковой? Это возможности самой ОС, если она не поддерживает работу с динамическими библиотеками, то хоть на бейсике пиши. А так, всё что ты написал про библиотеки на Амиге подходит и под винду. Основная идея dll не таскать один и тот же код по памяти двести раз и в случае смены кода не рекомпилировать каждую программу, использующую данную библиотеку.

icebear
12.10.2006, 17:52
Вообще на амиге одна либла на всех она не дублируется в памяти.

Это был бы т.н. singleton pattern. А что же вы делаете с данными в этом случае? Тоже одни на всех вызывающих? Как же потоки работают?

acidrain
12.10.2006, 18:01
Нифиганепонял. Причём здесь язык программирования как таковой? Это возможности самой ОС, если она не поддерживает работу с динамическими библиотеками, то хоть на бейсике пиши. А так, всё что ты написал про библиотеки на Амиге подходит и под винду. Основная идея dll не таскать один и тот же код по памяти двести раз и в случае смены кода не рекомпилировать каждую программу, использующую данную библиотеку.
Зачем таскать по памяти? Нипонял я! Зачем один и тот же код в разных прогав хранить на винте и в памяти, если можно только один раз на винте!
ХЛЛ тут при том, что куски своих либл (функций) линкует с прогой, даже если они (либы) там вапще не нуны. При чем тут ось?
Данные разные для каждого потока, по другому не могу представить, управляется сигналами/семафорами. Как говорит один мой друг - в винде почти тоже самое, но топорнее =)

icebear
12.10.2006, 18:06
Зачем таскать по памяти? Нипонял я! Зачем один и тот же код в разных прогав хранить на винте и в памяти, если можно только один раз на винте!

Дак о чём тебе и твердят. На амиге так же сделано, как и на винде (ну или наоборот, на винде как на амиге).


ХЛЛ тут при том, что куски своих либл (функций) линкует с прогой, даже если они (либы) там вапще не нуны.

Я не знаю что такое ХЛЛ, но нового ты ничего не сказал.


При чем тут ось?

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


Данные разные для каждого потока, по другому не могу представить, управляется сигналами/семафорами. Как говорит один мой друг - в винде почти тоже самое, но топорнее =)

Ну тогда чем тебя возмутило сообщение от elf/2? Он тебе тоже сказал, другими словами.

acidrain
12.10.2006, 18:11
При том, что в винде задача загрузки/выгрузки библиотек возложена на неё и она смотрит и следит за тем, кто юзает библиотеку, кто её реально использует, а кто уже отвалился.

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

acidrain
12.10.2006, 18:13
Линк на либмана я пару раз упоминал на этом форуме - 0 заинтересовавшихся

Если интересующихся наберется >= 3, то обещаю портировать со спринтера на спектрум - примеры либ в этом формате имеются, штука сильно перспективная была, да вот тока спринтер загнулся...
Дык заинтересованых нет? Может заинтересуетесь?

yoko_ono
12.10.2006, 18:50
Я же говорю несколько о другом. О runtime-самосборке программ из имеющихся на диске библиотек. В этом случае не страшна и самомодификация и имеется полная власть над памятью. За это дело придется платить задержками при загрузке (или собрать все в моноблок и получить обычную программу).

Ой ли - так прям и полная? Вы же сами говорите - либы совершенствуются и, следовательно, увеличиваются в размерах - и становится невозможно угадать кол-во свободной памяти!
Одно дело пц, с 4 гигами виртуалки и 32битной адресацией, а другое дело - спектрум...



ЗЫ. Изначально моя мысль стремилась к следующему- доработать мою модульную структуру до вида, применимого в некоторых моих программах.
То есть, вы намеренно решили затормозить загрузку программы для end-юзера? Чтобы он слушал спазмы дисковода, шныряющего по всему диску, ради сомнительного удобства программиста?...

elf/2
12.10.2006, 19:00
ну блин мы и понаписали :) а толку пока действительно мало :(


либ на какой стадии линкуется с прогойй - когда ее только компилируешь или когда ее запускает конечный юзер?
возможны варианты:
1. библиотека линкуется с программой статически т.е. на этапе компиляции/линковки
2. система поднимает библиотеку при старте программы
3. библиотека подгружается по запросу из программы (это как раз те примеры что я приводил)

кстати, когда я говорил что Windows/Linux реализация более гибкая я имел в виду как-раз эти три варианта. зачем все это:
1. программа не зависит от того какие библиотеки есть на машине пользователя
2. размер программы - маленький. никаких дополнительных телодвижений (руками загружать/истать адрес функции) не надо
3. для реализации "плагинов" в этом случае программа может работать с библиотеками которых не было во время ее создания через некое API


еще раз про handle возвращаемый из LoadLibrary - это просто число никак не связанное с адресом загрузки


а теперь IMHO: динамические библиотеки нужны в основном для системных программ, на спекки ими пользоваться будет не сильно удобно поскольку мы завязаны на floppy-ки.

ng_dead
12.10.2006, 19:01
Вы же сами говорите - либы совершенствуются и, следовательно, увеличиваются в размерах
Из чего это следует? Может ноаборот... уменьшаются?

и становится невозможно угадать кол-во свободной памяти!
А что гадать то? Не надо гадать. В самом примитивном случае, строится табличка распределения памяти между библиотеками...

elf/2
12.10.2006, 19:05
То есть, вы намеренно решили затормозить загрузку программы для end-юзера? Чтобы он слушал спазмы дисковода, шныряющего по всему диску, ради сомнительного удобства программиста?.
возможно я не правильно понял исходный пост Витамина, но он в последней строчке написал:


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

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

psndcj
12.10.2006, 19:21
Можно я встряну? Ну совсем чуть-чуть...

Лично мне для тех программ - типа системных (конверторы и различные пакеры) - пригодились бы всего-навсего пара плагинов - работа с диском (сэйв/лоад/выбор файла из каталога/ввод имени для сэйва) и некое подобие ГУИ (то есть надпись чтоб вывести если надо ну могет и выбрать чтонить на экране). в принципе это я уже сам для себя написал - правда в непотребном виде, удовлетворяющем меня одного. Реализовано именно как инклуд на этапе компиляции (то есть либа - так? =) )

Если бы были реально написаны модули с подобными возможностями, которые можно было бы просто использовать - не сомневаюсь, что я стал бы их использовать...

Насчет времени загрузки и прочего - если не лазить в каталог для определениякоординат файла на диске, то загрузка 2-3 файлов будет практически незаметна даже на реале... А при отсутствии операционки что-то я сомневаюсь в появлении программ, использующих десятки (сотни!!! =) ) подобных модулей... Лично я могу придумать еще парочку реально нужных и все...

Извините, что я тут в грязных в сапогах и в душу, ладно?

yoko_ono
12.10.2006, 19:22
Это был бы т.н. singleton pattern. А что же вы делаете с данными в этом случае? Тоже одни на всех вызывающих? Как же потоки работают?

Просто либы пишутся в реентерабельном стиле. Все локальные данные - на стеке, если надо - для каждого приложения заводится объект, адрес которого передаётся функциям.
Данные естественно одни, ибо нет системы виртуальной памяти. Потоков тоже нет (в АОС) - только отдельные task'и.

Vitamin
12.10.2006, 19:23
становится невозможно угадать кол-во свободной памяти!
Здесь согласен, проблема. Надо искать пути выхода.
(тем не менее, при динамической линковке и "либах в банках" ее угадать не менее невозможно)


То есть, вы намеренно решили затормозить загрузку программы для end-юзера? Чтобы он слушал спазмы дисковода, шныряющего по всему диску, ради сомнительного удобства программиста?...
Есть такая штука- кеширование.... Обычно изрядно облегчает жизнь и ускоряет работу.

Мдаблин... Прям военные действия... Хотя должен признать, единственный мой конструктивный диалог это с yoko_ono (хотя и не без предвзятости). Все остальное место ветки acidrain доказывает, что одно и то же понятие на амиге и винде называется по разному и всячески игнорирует ответы на свои же вопросы (это я о просьбе показать пример подключения библиотеки и вызова функции).
2Shaos: информацию по libman я прочитал сразу, как только acidrain выложил ссылку. И задал несколько вопросов, получив ответы только на половину. Так что согласен, что интереса- 0...

2acidrain: давай начнем с терминологии (надо было с этого и начинать...). итак, имеем 3 вида управления кодом программы
1) Статическая линковка. Объектные файлы, созданные заранее, подключаются к бинарнику на этапе компиляции и присутствуют в исполнимом файле. Во время работы не требуется никаких дополнительных движений со стороны программы чтобы подключить эти объектные файлы, просто прямые вызовы на функции. В простейшем случае, объектные файлы, скомпилированные из разных исходных текстов собираются в итоговый бинарник. При подключении одной и той же библиотеки в две разные программы данные физически дублируются. Примеры- a,obj,lib файлы (первое что на ум пришло)
2) Динамическая линковка. Объектные файлы подключаются во время работы программы путем открытия библиотеки (неважно, кто это делает, ОС или само приложение). Дальнейший вызов функций осуществляется на основе имеющегося описателя подключенной библиотеки. При подключении одной и той же библиотеки в две разные программы (для многозадачных ОС), код не дублируется. Примеры- so,dll.
3) Прочее. В частности, отсутствие линковки на уровне бинарных файлов, только на уровне исходных текстов на этапе компиляции. Использование только внутренних функций или функций ОС (в общем случае, если таковая имеется).

Есть вопросы? исправления? дополнения?

Vitamin
12.10.2006, 19:26
т.е конечный пользователь всей этой кухни не увидит, возможно кроме некоторых тормозов при старте для настройки библиотек на конкретные адреса
После прохода автосборщика в итоге получаем обычный бейсик-файл, в котором уже все внутри и никаких дополнительных телодвижений на подгрузку не делается. Т.е. по сути превращаем динамически-статическую (у меня именно такой вариант, не вписывающийся в мою же классификацию :)) линковку в чисто статическую.

icebear
12.10.2006, 19:44
Просто либы пишутся в реентерабельном стиле. Все локальные данные - на стеке, если надо - для каждого приложения заводится объект, адрес которого передаётся функциям.

Ах вот оно что! Винда наоборот :) Не в эту тему вопрос - а событийная модель там есть?


Данные естественно одни, ибо нет системы виртуальной памяти. Потоков тоже нет (в АОС) - только отдельные task'и.

Погоди, а разве амига не умеет читать с диска и чего-нибудь ещё делать параллельно? Как это можно сделать без потоков (в том смысле, что бы работало всегда и везде)?

И ещё оффтоп: на аватаре кошка из Ивана Васильевича?

icebear
12.10.2006, 19:47
Есть вопросы? исправления? дополнения?

По объектным файлам: разве это не те файлы, которые содержат исполняемый код, но не имеют "обёртки" (сиречь заголовка)? Потому как exe от dll по идее не сильно отличаестя, точнее отличается тем, что exe функций не экспортирует.

acidrain
12.10.2006, 19:55
(это я о просьбе показать пример подключения библиотеки и вызова функции).
2Shaos: информацию по libman я прочитал сразу, как только acidrain выложил ссылку. И задал несколько вопросов, получив ответы только на половину. Так что согласен, что интереса- 0...
Хмм я ж выложил. ты не читаешь, да?
Кому вопросы задавал?
Я за 2й пункт. Наконец то конструктивный разговор прорисовывается.
Но никто не мешает Си написать для пункта 1. ;)
Конструктивно ты не хотел разговаривать - я выкладывал, искал, пытался услышать вопросы. Ничего не было. Есть вопросы - задавай. Могу скинуть на мыло 10мб исходников святая-святых exec.library (единственная либла написаная в асме, а не в си). Также около 30 мб rom kernel manuals - будет желание проштудировать и понять всю систему из нутри? =)

yoko_ono
12.10.2006, 20:07
HMODULE h = LoadLibrary(pluginName);
FOO fn = (FOO)GetProcAddress(h,"foo");
(*fn)();
CloseHandle(h);

или линуксового:

m = dlopen("libsample.so", RTLD_LAZY);
fn = (FOO)dlsym(m, "foo");
(*fn)();
dlclose(m);

И такой ужас ДЛЯ КАЖДОЙ функции?..

На амиге сделано оптимальным образом - для вызова функции достаточно знать, в какой из jmp в таблице вызовов надо попасть (а не извлекать смещение для каждой функции отдельно), и вдобавок базовый адрес (где эта таблица вызовов, то есть). Как я думаю, проблема с пц в том, что целый регистр отдать под базовый при вызове через таблицу jmp - непозволительная роскошь для убогой х86 архитектуры.

yoko_ono
12.10.2006, 20:12
Из чего это следует? Может ноаборот... уменьшаются?

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



А что гадать то? Не надо гадать. В самом примитивном случае, строится табличка распределения памяти между библиотеками...

Обычно все нормальные программисты на Спектруме подразумевают, что у них в запасе вполне определённый объём памяти, который можно выяснить на этапе компиляции программы, например. А если эти так называемые библиотеки будут иметь непредсказуемый размер?

Vitamin
12.10.2006, 20:17
По объектным файлам: разве это не те файлы, которые содержат исполняемый код, но не имеют "обёртки" (сиречь заголовка)? Потому как exe от dll по идее не сильно отличаестя, точнее отличается тем, что exe функций не экспортирует.
По идее да, например на линухе результат сборки (объектный файл или разделяемая библиотека) зависит от ключей компилятора (если не собирается программа с main(int argc, char const * argv[])) В винде же надо еще прописывать дополнительные спецификаторы в заголовках, в зависимости от того импортируется или экспортируется функция.


Я за 2й пункт.
В смысле за динамическую компоновку? При условии отсутствия ОС применимо только в плагинной системе...


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


(единственная либла написаная в асме, а не в си)
Нафиг (почему- см. выше). В такой ситуации ближе С. А еще полезнее- внятная дока по формату (вроде есть где-то у меня). Потому как по сырому примеру мало что поймешь


И такой ужас ДЛЯ КАЖДОЙ функции?..
На амиге сделано оптимальным образом - для вызова функции достаточно знать, в какой из jmp в таблице вызовов надо попасть (а не извлекать смещение для каждой функции отдельно), и вдобавок базовый адрес (где эта таблица вызовов, то есть). Как я думаю, проблема с пц в том, что целый регистр отдать под базовый при вызове через таблицу jmp - непозволительная роскошь для убогой х86 архитектуры.
Смотрим внимательнее на тот исходник. Вызов функции (многократный) там занимает одну строчку. Все остальное- подготовка библиотеки и ее освобождение. Это однократно выполняемая последовательность.
Данный подход (принудительная загрузка библиотеки и получение адреса функции) применяется только при организации плагинной системы- получаем список плагинов, подключаем нужный когда надо, получаем из него адреса нужных функций, работаем с ними, освобождаем плагин. (При использовании ООП (современный подход) из плагина выковыривается одна-единственная функция- фабрика классов, которая производит экземпляры плагинно-зависимых классов, вызов функций которых происходит с помощью механизма полиморфизма).
Если имена модулей известны на этапе компиляции, то можно заставить компилятор генерировать специальный код, подключающий библиотеку при старте программы. При этом работа с ее функциями ведется совершенно прозрачно для программиста.

acidrain
12.10.2006, 20:30
2acidrain: давай начнем с терминологии (надо было с этого и начинать...). итак, имеем 3 вида управления кодом программы
1) Статическая линковка. Объектные файлы, созданные заранее, подключаются к бинарнику на этапе компиляции и присутствуют в исполнимом файле. Во время работы не требуется никаких дополнительных движений со стороны программы чтобы подключить эти объектные файлы, просто прямые вызовы на функции. В простейшем случае, объектные файлы, скомпилированные из разных исходных текстов собираются в итоговый бинарник. При подключении одной и той же библиотеки в две разные программы данные физически дублируются. Примеры- a,obj,lib файлы (первое что на ум пришло)
2) Динамическая линковка. Объектные файлы подключаются во время работы программы путем открытия библиотеки (неважно, кто это делает, ОС или само приложение). Дальнейший вызов функций осуществляется на основе имеющегося описателя подключенной библиотеки. При подключении одной и той же библиотеки в две разные программы (для многозадачных ОС), код не дублируется. Примеры- so,dll.
3) Прочее. В частности, отсутствие линковки на уровне бинарных файлов, только на уровне исходных текстов на этапе компиляции. Использование только внутренних функций или функций ОС (в общем случае, если таковая имеется).

Есть вопросы? исправления? дополнения?
Чего ты сразу с терминологии не начал? без моей помощи не мог разобраться что как называется? темболее ниже пишешь, что твое творение ни под один пункт не подходит, тогда что ты придумал?
Ты опубликовал свою идею для получения одобрения или посоветоваться - вот мой совет: не пытайтесь усложнить ищите более простые пути решения. ИМХО АОС для этих целей (подражание) подходит куда лучше, чем винда или линух.
Есть вообще готовое - Шаос либман. Бери, юзай! Развивай! Не изобретай велик!

acidrain
12.10.2006, 20:36
не на все из них получил ответы
я и так много нафлеймил, но тут простите - цитату в студию! что ты спрашивал? про второй вид либл - читай недопц форум, или его мне тоже наддо переписать?
А по первой - читай сайт шаоса, я не буду за тебя думать! не проси =)))

При условии отсутствия ОС применимо только в плагинной системе...

аргументируй !

Смотрим внимательнее на тот исходник. Вызов функции (многократный) там занимает одну строчку. Все остальное- подготовка библиотеки и ее освобождение. Это однократно выполняемая последовательность.
А если несколько ф-ций из одной либлы вызвать, при чем один вызов в либле 1, другой в либле2, затем 4, затем 1 - как быть в таком случае?

А тут налетел народ и давай расхваливать амигу (притом чисто на словах, безо всякой полезной для меня информации)
До этого ты писал, что спасибо за инфу, она так полезна. Теперь ты пишешь, что я ничче и не писал вовсе? И народу то сколько налетело амижного? Я и неизвестно откуда прошаренная йака_ини. А теперь посчитай скоко народу пцшного напало на меня?

Vitamin
12.10.2006, 21:01
но тут простите - цитату в студию! что ты спрашивал?
По поводу таблиц релокации. Мне интересно знать их устройство. Есть доки? В исходниках ковыряться ресурсоемко :)


аргументируй !
Пожалуйста. Для загрузки библиотеки по требованию необходим некий менеджер этих библиотек, а также менеджер памяти для распределения ресурса. Поскольку у нас нет ОС, то ясно, что эти менеджеры программа вынуждена таскать с собой. Все библиотеки подключаются один раз и ни разу не отключаются (в таком случае менеджер получается "одноразовый") Если это не так, то получаем плагинную систему (то, о чем я и говорил).
По сути, я предлагаю именно такую систему, но с некоторыми принципиальными отличиями:
-приложение ничего само не подключает, все делает загрузчик
-расположение библиотек не фиксированно, а выбирается сообразно обстоятельствам (в простейшем случае, одна за одной в памяти)
-керналя нет, при линковке подставляются непосредственные адреса вызова.


А если несколько ф-ций из одной либлы вызвать, при чем один вызов в либле 1, другой в либле2, затем 4, затем 1 - как быть в таком случае?
Если имена либ неизвестны на этапе компиляции, то открываем необходимое число библиотек, достаем из них указатели на функции и вызываем по этим указателям нужное число раз. Если имена известны, то этими всеми операциями (открытие-получение адреса-закрытие) обычно заведует ОС

captain cobalt
12.10.2006, 23:22
Итак, попробуем сформулировать основные принципы амижной реализации:

1. Импорт по номеру (ординалу) функции.
2. Использование dynamic binding вместо dynamic linking.

Недостаток первого пункта - отсутствие возможности контроля целостности во время загрузки.

Второй пункт означает что библиотеку можно рассматривать как ООП класс (и объект singleton) и функции вызываются как "виртуальные функции". Недостаток - перерасход ресурсов во время выполнения. Даже на Мотороле, где косвеный вызов по таблице адресов делается одной командой, необходим регистр (весьма ценный ресурс). А если надо будет вперемешку вызывать функции из разных библиотек? На Z80 понадобится гораздо больше машинных команд только для того, чтобы передать управление в библиотеку, и, в зависимости от реализации, некоторые регистры могут оказаться недоступными для передачи аргументов. При таком раскладе, считаю, рассказы о "каматозе динамической компоновки" мoжно отбросить.

Ах вот оно что! Винда наоборот :) В этом аспекте считаю подход Амиги (и Линукса) более правильным.
Так называемые "thread-safe libraries".

а теперь IMHO: динамические библиотеки нужны в основном для системных программ, на спекки ими пользоваться будет не сильно удобно поскольку мы завязаны на floppy-ки. Именно потому, что завязаны на floppy, динамическая компоновка может помочь.
Чем больше времени мы сможем хранить библиотеки в памяти и прикомпоновывать их к разным программам, тем больше ресурсов floppy может быть сэкономлено.

yoko_ono
12.10.2006, 23:54
По поводу таблиц релокации. Мне интересно знать их устройство. Есть доки? В исходниках ковыряться ресурсоемко :)


Cовершенно примитивное. Каждый 'exe' - после загрузки в память представляет из себя некоторое кол-во секций, с кодами, с данными и т.д. Если в секции есть абсолютные адреса со ссылками на к.-л. секцию - то в самом файле ставится относительное смещение от начала этой секции, а в таблице релокации для данной секции - смещение до адреса, который надо подкорректировать и номер секции, в которую он должен указывать. Плюс вариации с 16-32 битными смещениями. Вот и всё.

captain cobalt
13.10.2006, 00:12
1. Импорт по номеру (ординалу) функции.
2. Использование dynamic binding вместо dynamic linking. Ещё уточнения:

Смещения (в таблице адресов) вкомпилируются в бинарник и вообще недоступны загрузчику.

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

По сути, я предлагаю именно такую систему, но с некоторыми принципиальными отличиями:
-приложение ничего само не подключает, все делает загрузчик
-расположение библиотек не фиксированно, а выбирается сообразно обстоятельствам (в простейшем случае, одна за одной в памяти)
-керналя нет, при линковке подставляются непосредственные адреса вызова. Это поддерживаю на 100%
______________________

А вот ещё одна идея. :)

Заархивировать программы в непрерывный RAR архив.
Непрерывная архивация сожмёт одинаковый код в разных программах.
И степень сжатия приличная.
Осталось только на основе ZX-UnRAR сделать запускалку, которая будет распаковывать нужную программу в память и передавать ей управление. :)

captain cobalt
13.10.2006, 00:19
Каждый 'exe' - после загрузки в память представляет из себя некоторое кол-во секций, с кодами, с данными и т.д. Если в секции есть абсолютные адреса со ссылками на к.-л. секцию - то в самом файле ставится относительное смещение от начала этой секции, а в таблице релокации для данной секции - смещение до адреса, который надо подкорректировать и номер секции, в которую он должен указывать. Плюс вариации с 16-32 битными смещениями. Вот и всё. Как называется корректировка секций по таблицам релокаций? :)

Vitamin
13.10.2006, 00:46
в самом файле ставится относительное смещение от начала этой секции, а в таблице релокации для данной секции - смещение до адреса, который надо подкорректировать и номер секции, в которую он должен указывать.
Ну да. Сам такое делал. У меня только гибкость немного больше- есть возможность ссылаться на функции в других модулях и делать загрузку неполного адреса (старшего либо младшего байта)


Заархивировать программы в непрерывный RAR архив.
Непрерывная архивация сожмёт одинаковый код в разных программах.

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


Это поддерживаю на 100%
Ну вот. Лишний раз убеждаюсь, что в споре часто рождается истина (по крайней мере, для меня). Сколько мы с тобой дискутировали на тему ОС? :) Я много чего почерпнул для себя. Здесь несколько похуже, но думаю ситуация исправится.

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

elf/2
13.10.2006, 11:08
И такой ужас ДЛЯ КАЖДОЙ функции?..

конечно нет:
1. открываем библиотеку
2. получаем указатель на fn1
3. получаем указатель на fn2
...

n. пользуем функции
n+1. закрываем библиотеку



На амиге сделано оптимальным образом - для вызова функции достаточно знать, в какой из jmp в таблице вызовов надо попасть (а не извлекать смещение для каждой функции отдельно), и вдобавок базовый адрес (где эта таблица вызовов, то есть). Как я думаю, проблема с пц в том, что целый регистр отдать под базовый при вызове через таблицу jmp - непозволительная роскошь для убогой х86 архитектуры.
дело не в "убогости" архитектуры, а в том что подобный метод доступа к библиотекам используется очень редко. обычно библиотека линкуется динамически и система занимается "получением указателей". с точки зрения программиста в этом случае ничего открывать не надо, адреса тоже ресолвить не надо. он просто зовет нужную функу и все. вот это действительно оптимально :)

elf/2
13.10.2006, 11:22
вообще еще раз мое imho. динамическая компоновка (т.е. dll/so/exec.library) на текущем этапе на спекке на нужна, потому что:
1. оси нет, значить компоновщик придется добавлять СТАТИЧЕСКИ в каждую программу
2. даже если мы используем только одну функу из библиотеки в памяти будет висеть вся либа
!!! а памяти у нас не густо :(
3. поскольку библиотеки фактически ищутся по имени файла, загрузка всего приложения будет идти очень долго (придется каждый раз мотаться в каталог и обратно). если каталог кешировать для ускорения, то опять упираемся в память...
4. как правильно подметил psndcj реально нужны 2-3 библиотеки, стоит ли из-за этого огород городить?
5. у нас нет многозадачности, соответсвенно использования одной библиотеки несколькими приложениями не будет, следовательно экономии памяти от использования одного кода несколько раз тоже не будет

оригинальное предложение Витамина т.е. сборка из объектников (на мой взгляд опять же) имеет больше перспектив

ng_dead
13.10.2006, 11:54
мое imho
+1

acidrain
13.10.2006, 18:07
Если имена либ неизвестны на этапе компиляции, то открываем необходимое число библиотек, достаем из них указатели на функции и вызываем по этим указателям нужное число раз. Если имена известны, то этими всеми операциями (открытие-получение адреса-закрытие) обычно заведует ОС
Что значит имена не известны? А как кодер их должен юзать, если он не знает их имена? По функциям запрос делать, что ли?

По сути, я предлагаю именно такую систему, но с некоторыми принципиальными отличиями:
-приложение ничего само не подключает, все делает загрузчик
-расположение библиотек не фиксированно, а выбирается сообразно обстоятельствам (в простейшем случае, одна за одной в памяти)

Ну, я тебе вчера о том же намылил - загрузчик открывает и закрывает либлы.

Для загрузки библиотеки по требованию необходим некий менеджер этих библиотек, а также менеджер памяти для распределения ресурса. Поскольку у нас нет ОС, то ясно, что эти менеджеры программа вынуждена таскать с собой. Все библиотеки подключаются один раз и ни разу не отключаются (в таком случае менеджер получается "одноразовый") Если это не так, то получаем плагинную систему (то, о чем я и говорил).
Не путайся и не путай народ - цитата: то получаем плагинную систему
опять ты пишешь менеджеры с собой (один менеджер загрузчик для всех! типа boot). Никаких плагинов (можно, но не к теме) - тут именно набор стандартных ф-ций, которые юзают любые проги (одназадачная оська;) с выходом в ось 8) а не в васик/тырдос.
Cовершенно примитивное. Каждый 'exe' - после загрузки в память представляет из себя некоторое кол-во секций, с кодами, с данными и т.д. Если в секции есть абсолютные адреса со ссылками на к.-л. секцию - то в самом файле ставится относительное смещение от начала этой секции, а в таблице релокации для данной секции - смещение до адреса, который надо подкорректировать и номер секции, в которую он должен указывать. Плюс вариации с 16-32 битными смещениями. Вот и всё.
Все верно! Я поражен Вами, жаль женат и две дочки, а тоб ;)))
но Витамин спрашивал о libman либах а не об амиге!
2Витамин:Предполагаю, что все в либмане с релокацией просто, как то изучал исходники на Срр (они там в архивах, есть даже .ехе для авто реклокации или что то типа того - не помню 4 года прошло)
И еще, все вопросы по либману - к автору: Shaos, пиши на мыло, в его форум, аську - не спрашивай меня об этом, ок?
И не выдумывай, повторюсь, велосипед - либман - готовый, проработанный формат и легко автором портируется на спек - пользуйся тем, что уже готово! А так, если жаждишь славы - то дерзай.
Могу выслать мою первую либлу (если найду - на листочках хранил), которую я писал для спека и системы, как я описал выше. Тама мышко-драйвер типа :)

acidrain
13.10.2006, 18:11
Даже на Мотороле, где косвеный вызов по таблице адресов делается одной командой, необходим регистр (весьма ценный ресурс)
Можешь регистром пользоваться, как заблагорасудится! =) Никто не запрещает его юзать - он не постоянно нужен, только при обращении к либле. Остальное время можешь про него забыть и юзать постоянно, до следующегно вызова. Система такова, что берешь хендл либлы в регистр, а по возвращению - он опять твой. Как и любой другой регистр, необходимый для передачи данных в либлу.
Надеюсь понятно изъяснил. Такчто не ресурсоемкий метод!

acidrain
13.10.2006, 18:25
конечно нет:
1. открываем библиотеку
2. получаем указатель на fn1
3. получаем указатель на fn2
...

n. пользуем функции
n+1. закрываем библиотеку
А, простите меня, грешного, на амиге - не надо получать указатели на ф-ции! вот в чем финт.

дело не в "убогости" архитектуры, а в том что подобный метод доступа к библиотекам используется очень редко. обычно библиотека линкуется динамически и система занимается "получением указателей". с точки зрения программиста в этом случае ничего открывать не надо, адреса тоже ресолвить не надо. он просто зовет нужную функу и все. вот это действительно оптималь
Ну лично для меня (!) такой распространенный метод как динамически линкуемая либла - лезть зубочисткой через зад! Зачем оське знать, где какая ф-ция (тем более у стороннего производителя либл)? Ей надо другими вещами заниматься, например реалтаймом ;)

acidrain
13.10.2006, 18:30
4. как правильно подметил psndcj реально нужны 2-3 библиотеки, стоит ли из-за этого огород городить?
Стоит - это начало из начал ... для оси :)

elf/2
13.10.2006, 19:16
А, простите меня, грешного, на амиге - не надо получать указатели на ф-ции! вот в чем финт.
зато прямой вызов по известному адресу быстрее :)

Ну лично для меня (!) такой распространенный метод как динамически линкуемая либла - лезть зубочисткой через зад! Зачем оське знать, где какая ф-ция (тем более у стороннего производителя либл)? Ей надо другими вещами заниматься, например реалтаймом
ось должна облегчать жизнь пользователя в первую очередь и программиста во вторую. что винда/линукс и делают. в результате уменьшается размер кода и число ошибок (нельзя забыть проинициализировать либу, ошибки линковки обрабатываются системой, нет никакой разницы для программиста между статической/динамической линковкой)
а механизм там простой до безобразия: у либы есть список экспортируемых функций а у проги - список jump'ов на импортируемые. при загрузке винда список jmp'ов корректирует

icebear
13.10.2006, 19:19
Что значит имена не известны? А как кодер их должен юзать, если он не знает их имена? По функциям запрос делать, что ли?

Почитай про COM, там по дефолту вообще только три функции декларированы. Вот где башка кипеть начнёт.

elf/2
13.10.2006, 19:32
Что значит имена не известны? А как кодер их должен юзать, если он не знает их имена? По функциям запрос делать, что ли?
очень просто. есть API - некий набор функций. некие библиотеки этот API поддерживают

при загрузке приложения ищем файлы по маске (например 'plugins/*.dll'). каждый файл по очереди грузим через LoadLibrary, и получаем из каждой библиотеки нужные функции.
если файло загрузилось и нужные функции нашлись то спокойно используем (кстати в ruby для этого (ну почти для этого :) даже спецтермин придумали - duck typing)

Vitamin
13.10.2006, 19:50
Не путайся и не путай народ - цитата: то получаем плагинную систему
опять ты пишешь менеджеры с собой (один менеджер загрузчик для всех! типа boot). Никаких плагинов (можно, но не к теме) - тут именно набор стандартных ф-ций, которые юзают любые проги (одназадачная оська с выходом в ось 8) а не в васик/тырдос.
Ща поясню. Плагинная система- сиречь ОС и приложения (только в другом масштабе). Одна большая хост-программа с навороченным менеджером и простенькие плагины. А если у нас нет хост-программы/ОСи, то лепить навороченный менеджер (заметь, в КАЖДУЮ программу) нет абсолютно никакого смысла.


И не выдумывай, повторюсь, велосипед - либман - готовый, проработанный формат и легко автором портируется на спек - пользуйся тем, что уже готово! А так, если жаждишь славы - то дерзай.
Я свою систему начал писать на год позже, чем датирована статья про libman. Ясное дело, ничего про него не знал, только имел некоторое представление о формате объектных файлов исдоса.

2Shaos: можно получить документацию по формату библиотек, возможностям и т.п. Потому как функциональности может быть недостаточно и придется "изобретать велосипед"...

acidrain
13.10.2006, 19:58
(заметь, в КАЖДУЮ программу)
Нет же, не в каждую!!!

yoko_ono
13.10.2006, 20:46
Смотрим внимательнее на тот исходник. Вызов функции (многократный) там занимает одну строчку. Все остальное- подготовка библиотеки и ее освобождение. Это однократно выполняемая последовательность.

Для КАЖДОЙ функции!



Данный подход (принудительная загрузка библиотеки и получение адреса функции) применяется только при организации плагинной системы- получаем список плагинов, подключаем нужный когда надо, получаем из него адреса нужных функций, работаем с ними, освобождаем плагин. (При использовании ООП (современный подход) из плагина выковыривается одна-единственная функция- фабрика классов, которая производит экземпляры плагинно-зависимых классов, вызов функций которых происходит с помощью механизма полиморфизма).
Если имена модулей известны на этапе компиляции, то можно заставить компилятор генерировать специальный код, подключающий библиотеку при старте программы. При этом работа с ее функциями ведется совершенно прозрачно для программиста.

Ну вот, вы сами и написали, что в любом случае дело сводится к выковыриванию абсолютных адресов КАЖДОЙ функции, либо руками, либо стартап-кодом!

yoko_ono
13.10.2006, 20:51
конечно нет:
1. открываем библиотеку
2. получаем указатель на fn1
3. получаем указатель на fn2
...

n. пользуем функции
n+1. закрываем библиотеку

Получаем указатель для КАЖДОЙ используемой функции, как же 'конечно нет'?



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

Оптимально ли? С каждым ехешником путешествуют лишние ссылки релокации, а если какой-нибудь, даже мелкой, либы нету - то ехешник осью в принципе не загрузится. Хотя программист мог бы решить по ходу дела, что если либы нету, то и каких-то функций нет.

yoko_ono
13.10.2006, 21:02
2. даже если мы используем только одну функу из библиотеки в памяти будет висеть вся либа

Именно! В то время как компиляция либ из исходника позволяет компилировать только РЕАЛЬНО требуемые функции, а ведь именно от сборки либ из исходников Vitamin и хочет уйти!



оригинальное предложение Витамина т.е. сборка из объектников (на мой взгляд опять же) имеет больше перспектив

Ну на мой скромный взгляд, оригинальности тут на грош - идея 'цельнотянутая' с пц-винды-линуха.

Прежде всего его идея подразумевает релоцируемость. Коя реалтизуется на этапе компиляции в любом ассемблере или генераторе кода и поддерживается осью на пц/амиге/и т.д. На Спектруме же - ни того, ни другого. Существующие ассемблеры все как один не поддерживают релоцируемость (хитрости с макросами не в счёт). Да и вообще, парадигма программирования на Спектруме чужда релоцируемости - если, конечно же, не писать все программы в 'академическом' стиле программирования Z80.

Если уж так хочется либ, то можно предложить следующий механизм, свободный от релоцируемости как минимум user-программы (то бишь той, которая пользуется либами и грузит их с диска).

Юзер-прога грузит либу в статически определённое место в памяти. Та сама себя релоцирует каким-либо методом (пусть автор либы поупражняется, раз уж ему нечего делать, кроме как либы писать). И например в начале указанного user-программой места строит таблицу вызовов своих функций, состоящей из JP func1:JP func2:JP func3 и т.д. После чего user-программа, зная начало этой таблицы (раз уж она его и указала), делает туда CALL'ы. Можно отделить собственно тело библиотеки от таблицы вызовов. Можно тело библиотеки класть в страницу, перед вызовом включая её (нету оси - нету менеджера страниц, доступного библиотеке).

Shaos
14.10.2006, 05:40
2Shaos: можно получить документацию по формату библиотек, возможностям и т.п. Потому как функциональности может быть недостаточно и придется "изобретать велосипед"...

Дык вот же всё: http://www.nedopc.org/nedopc/shaos/libman_r.shtml

Поясню в двух словах - либы релоцируемы с шагом 256 байт (таблица релокации занимает 1/8 размера кода) во время загрузки. Либы при открывании накидываются друг за другом в страницу 16К пока не займут её полностью, потом ново-открываемые либы накидываются в другую страницу 16К и т.д. Страницы подключаются в нужные окна в момент вызова функций из соответствующей либы. Возможность задавать окно где либа будет вызываться нужна не только ради удобства программиста, но и например ради вызывания либы из другой либы (для этого они должны сидеть в разных окнах).

Vitamin
14.10.2006, 13:11
Получаем указатель для КАЖДОЙ используемой функции, как же 'конечно нет'?
Ржунимагу. А на амиге по индексу функции случайно не указатель на нее ищется (косвенный) для последующего перехода? Потому как, если нет указателя на функцию или ее адреса (разные вещи), то функцию вызвать невозможно!


Именно! В то время как компиляция либ из исходника позволяет компилировать только РЕАЛЬНО требуемые функции, а ведь именно от сборки либ из исходников Vitamin и хочет уйти!
Мадам! А вы про оптимизацию слышали? Когда из объектого кода (библиотек то есть) удаляются неиспользуемые функции? Конечно, данная операция применима только при сборке готовой программы, а не runtime-сборке, но тем не менее :lol
Да, кстати, как на этапе компиляции определить нужность-ненужность функций с учетом "парадигмы программирования на спектруме" и без "извратов с макросами"? Я, если честно, даже с извратами не смогу однозначно это определить.


Ну на мой скромный взгляд, оригинальности тут на грош - идея 'цельнотянутая' с пц-винды-линуха.
А глаза разуть и посмотреть, что идея динамической линковки одинакова и на амиге и на линухе и на винде (что неоднократно показывалось в этой ветке)? Разница только в технических тонкостях организации вызова.
ЗЫ. Если б идея была "цельнотянута" с амиги, тут бы наверное кипятком пИсали....


Прежде всего его идея подразумевает релоцируемость. Коя реалтизуется на этапе компиляции в любом ассемблере или генераторе кода и поддерживается осью на пц/амиге/и т.д. На Спектруме же - ни того, ни другого. Существующие ассемблеры все как один не поддерживают релоцируемость (хитрости с макросами не в счёт).
И почему же не в счет? И что мешает написать новый компилятор?


Если уж так хочется либ, то можно предложить следующий механизм, свободный от релоцируемости как минимум user-программы (то бишь той, которая пользуется либами и грузит их с диска).
user-программа свободно может быть и нерелоцируемой, ей это не нужно. Читаем внимательнее.

Shaos: выравнивание это хорошо. Но не всегда. Я у себя это опционально делаю. Еще вопросы
-из либы экспортируются только функции или могут экспортироваться данные?
-возможно ли при компиляции либы задать ссылки на внешние, неизвестные на этапе компиляции точки?
-если да, то как это описывается форматом
-каким образом компилируется релоцируемая либа? (особый компилятор, еще какие "извраты" :)))

acidrain
14.10.2006, 15:06
Потому как, если нет указателя на функцию или ее адреса (разные вещи), то функцию вызвать невозможно!
Нет, ты упорно не хочешь слышать, что тебе говорят! Нету никаких указателей на функции! Есть только хендл либлы и все! Ведь прежде чем вызвать ф-цию ты ведь должен знать, что она делает? Значит ты знаешь, в какой либле ее искать? То тогда ЗАЧЕМ тебе адрес или указатель на ф-цию?

acidrain
14.10.2006, 15:11
И что мешает написать новый компилятор?
Исторически слложившиеся пристрастия и нежелание все конвертировать из своего любимого асма в твой новый. Это еще один тормозящий фактор быстрого развития твоей идеи.

Shaos
14.10.2006, 15:41
Shaos: выравнивание это хорошо. Но не всегда. Я у себя это опционально делаю. Еще вопросы
-из либы экспортируются только функции или могут экспортироваться данные?
-возможно ли при компиляции либы задать ссылки на внешние, неизвестные на этапе компиляции точки?
-если да, то как это описывается форматом
-каким образом компилируется релоцируемая либа? (особый компилятор, еще какие "извраты" :)))

Только функции - доступ к данным через функции. Каждый экземпляр библиотеки будет иметь свои данные и свой код. Никаких внешних точек. Релоцируемая либа компилируется так - компилим с адреса #0000, потом компилим с адреса #0100 и побайтно сравниваем что получилось - если соответствующие байты в двух результатах компиляции отличаются, то пишем в соответствующий бит 1, иначе 0. Подобный фокус с релокацией прокатывает только если адреса указываются прымым текстом и не вычисляются хитрыми формулами. И соответсвенно не может быть никакой самомодификации кода либы с исправлениями адресов переходов.

elf/2
14.10.2006, 18:27
Оптимально ли? С каждым ехешником путешествуют лишние ссылки релокации, а если какой-нибудь, даже мелкой, либы нету - то ехешник осью в принципе не загрузится. Хотя программист мог бы решить по ходу дела, что если либы нету, то и каких-то функций нет.
по крайней мере более гибкий :) если либа обязательная, то пусть система сама все делает, если не обязательная - то пользуемся загрузкой через LoadLibrary

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

Получаем указатель для КАЖДОЙ используемой функции, как же 'конечно нет'?
видимо я не совсем понял Ваш исходный комментарий, мне показалось что Вы интересовались необходимостью всей конструкции (load, получить адрес, высвать, close). действительно необходимо получить адрес каждой используемой функции. или воспользоваться выше описанным подходом (используется например в Mirande)

Ну на мой скромный взгляд, оригинальности тут на грош
имел в виду: оригинальный = предложенный в первом посте темы

Нет, ты упорно не хочешь слышать, что тебе говорят! Нету никаких указателей на функции! Есть только хендл либлы и все! Ведь прежде чем вызвать ф-цию ты ведь должен знать, что она делает? Значит ты знаешь, в какой либле ее искать? То тогда ЗАЧЕМ тебе адрес или указатель на ф-цию?
ну что вы опять? вы оба правы:
1. не зная адреса - нельзя вызвать функцию напрямую
2. на амми ее напрямую никто и не зовет

captain cobalt
14.10.2006, 18:58
Про это я говорил уже, можно даже не сжимать, а просто в один файл сложить все либы дабы не шариться по диску при сборке. Взять статически скомпонованные программы.
В каждой программе может быть свой экземпляр библиотеки.

Сжать эти программы.
Непрерывное сжатие сожмёт дубликаты библиотек внутри программ. :)

+1 -1

оси нет, значить компоновщик придется добавлять СТАТИЧЕСКИ в каждую программу Это не обязательно. :)
Ось целиком может быть построена на динамическом компоновщике.
Даже управление памятью и параллелизм может работать поверх динамического компоновщика.

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

Можешь регистром пользоваться, как заблагорасудится! =) Никто не запрещает его юзать - он не постоянно нужен, только при обращении к либле. Остальное время можешь про него забыть и юзать постоянно, до следующегно вызова. Система такова, что берешь хендл либлы в регистр, а по возвращению - он опять твой. Как и любой другой регистр, необходимый для передачи данных в либлу.
Надеюсь понятно изъяснил. Такчто не ресурсоемкий метод! Загрузить хэндл в регистр - машинная команда и расход ресурсов. :)

таблица релокации занимает 1/8 размера кода Много.

Вызов функций библиотеки производится с помощью подпрограммы L_CALL.
Эта подпрограмма самостоятельно подключает необходимый код в нужное
окно (программист должен корректно указать его при загрузке
библиотеки, чтобы не закрыть открываемой страницей кода
менеджера, данных, стека), передает управление на код
соответствующей функции библиотеки, а затем возвращает обратно ту
страницу, которая была там до вызова функции библиотеки.
Перед вызовом в HL устанавливается идентификатор библиотеки, а в
регистре B - функция библиотеки, которую нужно вызвать. Регистр C
- зарезервирован на будущее:

ld hl,(handle)
ld b,function
call l_call
jp c,error

Об ошибке свидетельствует взведеный флаг переноса. Данные можно
передавать и получать в регистрах A,DE,IX,IY, а также через
второй набор регистров. Другими словами, четыре регистра недоступны для передачи аргументов.
Каждый вызов - потенциальная махинация со страницами.

Довольно прямолинейная реализация подхода Амиги.
А практичность результата? ;)

elf/2
14.10.2006, 21:22
оси нет, значить компоновщик придется добавлять СТАТИЧЕСКИ в каждую программу

Это не обязательно.
Ось целиком может быть построена на динамическом компоновщике.
Даже управление памятью и параллелизм может работать поверх динамического компоновщика.

ООП позволяет разбивать систему на подсистемы по абстракциям, а не по функциональности.
не понял что ты имел в виду :(
1. причем здесь ООП?
2. какой еще вариант кроме добавления компоновщика в каждую программу возможен если у нас нет ОСи?

elf/2
14.10.2006, 21:31
Если уж так хочется либ, то можно предложить следующий механизм, свободный от релоцируемости как минимум user-программы (то бишь той, которая пользуется либами и грузит их с диска).

Юзер-прога грузит либу в статически определённое место в памяти. Та сама себя релоцирует каким-либо методом (пусть автор либы поупражняется, раз уж ему нечего делать, кроме как либы писать). И например в начале указанного user-программой места строит таблицу вызовов своих функций, состоящей из JP func1:JP func2:JP func3 и т.д. После чего user-программа, зная начало этой таблицы (раз уж она его и указала), делает туда CALL'ы. Можно отделить собственно тело библиотеки от таблицы вызовов.
кстати примерно так сделано на винде когда либа подгружается системой :)

только в качестве списка jmp'ов используется таблица импорта программы и ее заполняет система на основании списка экспортируемых функций либы

Shaos
14.10.2006, 22:05
Много.

Плюс RLE сжатие файла либы, которое съест все нули, если в коде небыло переходов. На самом деле 1/8 от объема кода это вовсе немного, если учесть что в замен мы получаем настоящую перемещаемость с шагом 256 байт.


Другими словами, четыре регистра недоступны для передачи аргументов.
Каждый вызов - потенциальная махинация со страницами.
Довольно прямолинейная реализация подхода Амиги.
А практичность результата? ;)

Ну да - переключить страницу памяти это копейки времени. И всё работает. И пока никто не предложил что-то лучше ;)

P.S. Кроме того этот формат либ поддержан в компиляторе языка Форт и в компиляторе языка Си (оба на Спринтере)

captain cobalt
14.10.2006, 23:18
не понял что ты имел в виду :( Плохо.
Надо разбираться в ООП. Рекомендую книгу (http://www.intuit.ru/shop/product.xhtml?id=2493373&contents=1).

1. причем здесь ООП? Попробуем разобраться.
Есть "процедурное программирование" и есть ООП.
В чём отличие?
Процедурное программирование - это явное использование функциональности процедур. Например, для вывода спрайта используется процедура вычисления адреса в видеопамяти. При этом точно известно, что от неё ожидать, у программиста имеется реализация этой процедуры.

ООП расширяет эту модель, допуская неявное использование функциональности. Это называется "полиморфизм". Вызывая процедуру, программист уже не опирается на конкретную её реализацию. Реализация может быть неединственна, и, более того, один и тот же вызов в разные моменты времени может фактически обращаться к разным реализациям.

Рассмотрим на примере виндовых DLL.

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

Теперь посмотрим на FAR с плагинами. FAR, очевидно, явно загружает их с помощью LoadLibrary. При этом разработчики FAR не знают, что реализовано в плагине. Они лишь надеются что это нечто полезное. :) Это неявное использование функциональности.

(забавное сочетание: явное использование функциональности - неявная загрузка DLL; неявное использование - явная загрузка)

При чём здесь всё это?

ИМХО о пяти пунктах (http://zx.pk.ru/showpost.php?p=61111&postcount=85) насквозь пропитано духом процедурного программирования. "Чтобы был динамический компоновщик, нужно чтобы сначала была ось". Это не так. ООП даёт механизм преодоления. FAR запросто может использовать плагины, которых не существовало во время его написания.

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

2. какой еще вариант кроме добавления компоновщика в каждую программу возможен если у нас нет ОСи? Пусть у нас нет ни оси, ни программ, ни библиотек, есть только динамический компоновщик. Теперь, подсовывая этому компоновщику модули, можно построить хоть ось, хоть программу. Всё что угодно. :)

yoko_ono
15.10.2006, 01:02
Ржунимагу. А на амиге по индексу функции случайно не указатель на нее ищется (косвенный) для последующего перехода? Потому как, если нет указателя на функцию или ее адреса (разные вещи), то функцию вызвать невозможно!

Господин Vitamin, по-моему, вы скатились в абсурд. Что-то мешает вам адекватно воспринимать написанное?



Мадам!

Ну уж простите, это просто грубо! Я вам никакая не 'мадам'! Обращайтесь так к французским потаскушкам!!!



А вы про оптимизацию слышали? Когда из объектого кода (библиотек то есть) удаляются неиспользуемые функции? Конечно, данная операция применима только при сборке готовой программы, а не runtime-сборке, но тем не менее :lol

А вы слышали про это на СПЕКТРУМЕ?


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

Вы не знакомы со всеми возможностями alasm? Сочувствую...



И почему же не в счет? И что мешает написать новый компилятор?

Ничто не мешает, но почему-то не пишут. Задумайтесь, почему.



user-программа свободно может быть и нерелоцируемой, ей это не нужно. Читаем внимательнее.

Как это нерелоцируемой, если адреса вызовов ваших этих линкуемых библиотек всё равно меняются и информацию о них всё равно нужно хранить?

yoko_ono
15.10.2006, 01:08
ООП позволяет разбивать систему на подсистемы по абстракциям, а не по функциональности.
Загрузить хэндл в регистр - машинная команда и расход ресурсов. :)
Много.

А что, ваше хвалёное ООП разве не подразумевает использование указалетелей на объекты в регистрах и передачу этих указателей функциям? Труднее придумать что-либо более разбазаривающее ресурсы, чем ООП в реализации 'с-крест-крест'.



Другими словами, четыре регистра недоступны для передачи аргументов.
Каждый вызов - потенциальная махинация со страницами.

А сколько же регистров у ВАС в вашем ООП будет использовано? Не соизволите ли привести примеры?



Довольно прямолинейная реализация подхода Амиги.
А практичность результата? ;)
Скажите, вы в детстве не зачитывались ли 'зх-ревю' и 'спектрофонами' на ночь? По-видимому, зачитывались...

yoko_ono
15.10.2006, 01:12
Плохо.
Надо разбираться в ООП. Рекомендую книгу (http://www.intuit.ru/shop/product.xhtml?id=2493373&contents=1).

Признайтесь, вы - засланец секты ООП? Сколько вам заплатили за рекламу этой книги?



Попробуем разобраться.
Есть "процедурное программирование" и есть ООП.
В чём отличие?
Процедурное программирование - это явное использование функциональности процедур. Например, для вывода спрайта используется процедура вычисления адреса в видеопамяти. При этом точно известно, что от неё ожидать, у программиста имеется реализация этой процедуры.

ООП расширяет эту модель, допуская неявное использование функциональности. Это называется "полиморфизм". Вызывая процедуру, программист уже не опирается на конкретную её реализацию. Реализация может быть неединственна, и, более того, один и тот же вызов в разные моменты времени может фактически обращаться к разным реализациям.

Какое это имеет отношение к СПЕКТРУМУ? Способны ли вы 1 - привести пример реализации вашего 'ООП' на СПЕКТРУМЕ и 2 - продемонстрировать полученный при применении этого 'ООП' выигрыш в скорости работы или размере программы?

yoko_ono
15.10.2006, 01:17
только в качестве списка jmp'ов используется таблица импорта программы и ее заполняет система на основании списка экспортируемых функций либы

Вот именно - в отдельной части EXE хранится список ячеек, в которые надо подставить абсолютные адреса этих функций в момент приведения EXE в работоспособный вид (при загрузке), и создание таких списков - штатная функция генераторов кода на пц. На спектруме же такая операция - нештатная, и до сих пор осуществляется макросами, привнося множество ограничений и существенно усложняя и замедляя процесс компилирования программы, следовательно, необходимо уходить от такого механизма.
Варианты Shaos'а и мой свободны от любой модификации абсолютных адресов вызовов библиотечных функций в user-программе.

Vitamin
15.10.2006, 03:22
Нет, ты упорно не хочешь слышать, что тебе говорят! Нету никаких указателей на функции! Есть только хендл либлы и все! Ведь прежде чем вызвать ф-цию ты ведь должен знать, что она делает? Значит ты знаешь, в какой либле ее искать? То тогда ЗАЧЕМ тебе адрес или указатель на ф-цию?
Рассказываю. При классическом использовании либы происходит получение адреса функции (однократное) и ее вызов (многократный). На амиге же происходит вычисление адреса функции (многократное!) вместе с последующим многократным вызовом.


Исторически слложившиеся пристрастия и нежелание все конвертировать из своего любимого асма в твой новый. Это еще один тормозящий фактор быстрого развития твоей идеи.
Согласен. Как ни прискорбно, но согласен. Но в таком случае все идеи по реализации релоцируемых бинарников разбиваются об этот fuck'тор.


Только функции - доступ к данным через функции. Каждый экземпляр библиотеки будет иметь свои данные и свой код. Никаких внешних точек. Релоцируемая либа компилируется так - компилим с адреса #0000, потом компилим с адреса #0100 и побайтно сравниваем что получилось - если соответствующие байты в двух результатах компиляции отличаются, то пишем в соответствующий бит 1, иначе 0. Подобный фокус с релокацией прокатывает только если адреса указываются прымым текстом и не вычисляются хитрыми формулами. И соответсвенно не может быть никакой самомодификации кода либы с исправлениями адресов переходов.
Имхо маловато функционала. Весьма нехватает ссылок на внешние библиотеки для совместной работы.


Сжать эти программы.
Непрерывное сжатие сожмёт дубликаты библиотек внутри программ.
Не, дубликатов библиотек внутри программ быть не должно! Максимум- дубликаты функций.


Господин Vitamin, по-моему, вы скатились в абсурд. Что-то мешает вам адекватно воспринимать написанное?
Где я написал абсурд? Что для вызова функции надо иметь ее адрес или указатель на нее?


Ну уж простите, это просто грубо! Я вам никакая не 'мадам'! Обращайтесь так к французским потаскушкам!!!
Оп-па (поручик, молчать!!!!)! Феминизм в действии! Товарищ Елена, прощу прощения за излишнее проявление уважения к слабому полу и впредь буду пытаться выдерживать положенные 3 см дистанции :lol:


А вы слышали про это на СПЕКТРУМЕ?
Нуну. Каких-то пять лет назад на Спектруме не слышали ни о jpeg, ни о RAR, ни о еще многих вещах. Или то что я сказал совсем нереализуемо?


Вы не знакомы со всеми возможностями alasm? Сочувствую...
Исходник в студию.


Ничто не мешает, но почему-то не пишут. Задумайтесь, почему.
Пишут. SjASM название ничего не говорит? Если не ошибаюсь, у него с макросами все в порядке, как и у Alasm. А если идея широко пойдет в массы, можно раскочегарить автора на нативную поддержку генерации релоцируемого кода.


Как это нерелоцируемой, если адреса вызовов ваших этих линкуемых библиотек всё равно меняются и информацию о них всё равно нужно хранить?
Что есть релоцируемость? Возможность работы программы в любых адресах. А ссылки на функции в библиотеках- это дело уже отдельное (в общем случае). Так что главный модуль может быть прибит гвоздями к конкретному адресу, главное чтоб он под него и грузился. Ну и таблица смещений, где содержатся вызовы на внешние функции также нужна, несомненно.


Труднее придумать что-либо более разбазаривающее ресурсы, чем ООП в реализации 'с-крест-крест'.
Исключительно в целях повышения уровня своей образованности. Есть реализации ООП, менее разбазаривающее ресурсы? ООП имхо худо-бедно, но компромисс между функциональностью и ресурсоемкостью.


привести пример реализации вашего 'ООП' на СПЕКТРУМЕ
В одной из веток уже приводился. Первое что пришло в голову- вызов виртуальной функции:

;iy=this a=func index
add a,a
add a,(iy)
ld l,a
adc a,(iy+1)
sub l
ld h,a,a,(hl)
inc hl
ld h,(hl)
ld l,a
jp (hl)

Тяжеловато, не спорю. Использовал IY для хранения this чтоб можно было легко достучаться до членов класса. Для сравнения, вызов по индексу а-ля амига:
;a- func index hl-libr addr
add a,a
add a,a
add a,l
ld l,a
adc a,h
sub l
ld h,a
jp (hl)

исходил из предположения, что таблица переходов занимает 4 байта на точку. Если не 4, а 3 (обычный jp addr), то вызов будет еще больше.
Можно слегка оптимизировать, если располагать библиотеку с адреса кратного 256.

Сильно существенная разница получается?


Варианты Shaos'а и мой свободны от любой модификации абсолютных адресов вызовов библиотечных функций в user-программе.
Вариант Shaos'a видел. Ваш где, товарищ? ;)
А от чего он еще свободен? От возможности позднего связывания модулей между собой?

ЗЫ. А вот мой вариант позволяет безо всяких проблем реализовать керналь точек входа, если так хочется. А может и без него работать. Чего нельзя сказать о предлагаемом. А вот в собранной программе этот керналь- лишняя трата времени и памяти.

captain cobalt
15.10.2006, 08:36
А что, ваше хвалёное ООП разве не подразумевает использование указалетелей на объекты в регистрах и передачу этих указателей функциям? Да.
Каждый раз, когда данные не влезают в регистры, используют передачу через память. В ООП данные храняться в объектах и передаются указатели на объекты. В чем проблема? Чем хуже передачи указателей в "обычном программировании"?

А сколько же регистров у ВАС в вашем ООП будет использовано? Не соизволите ли привести примеры? Это неправильный вопрос.
Libman (и библиотеки Амиги) не претендует на ООП. А уже регистры как щепки летят. Лучше бы поинтересоваться, что получится, если попробовать реализовать ООП поверх него.

Скажите, вы в детстве не зачитывались ли 'зх-ревю' и 'спектрофонами' на ночь? По-видимому, зачитывались... К ним имеются какие-то претензии?

Признайтесь, вы - засланец секты ООП? Да, а в чём проблема? :)

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

Сколько вам заплатили за рекламу этой книги? Нисколько.

Способны ли вы 1 - привести пример реализации вашего 'ООП' на СПЕКТРУМЕ 1. Блочные драйверы iS-DOS (и других OS).
2. Драйверы расширенной памяти в ALASM (и многом другом).
3. GUI в BGE.

Все эти примеры справедливо считаются жемчужинами программирования на Speccy.

продемонстрировать полученный при применении этого 'ООП' выигрыш в скорости работы или размере программы? Основной выигрыш от ООП - гибкость.
Полезная функциональность часто является следствием гибкости. Полезная функциональность - это то что предстаёт перед конечным пользователем.

Именно отсюда следует брать область применимости ООП.

Скорость и размер при этом могут деградировать обратно пропорционально мастерству программиста. В особенности уровню владения ООП. :)

captain cobalt
15.10.2006, 08:55
Первое что пришло в голову- вызов виртуальной функции:

;iy=this a=func index
add a,a
add a,(iy)
ld l,a
adc a,(iy+1)
sub l
ld h,a,a,(hl)
inc hl
ld h,(hl)
ld l,a
jp (hl) Обычно func index для каждой конкретной точки вызова это константа.
Можно выполнить constant propagation. Получим:

LD L,(IY+Д)
LD H,(IY+Д+1)
JP (HL)
Этот кусок кода можно инлайнить. Можно ещё перед этим добавить PUSH HL, а в начало каждой виртуальной функции POP HL. Соответственно HL станет доступным для передачи аргументов в виртуальную функцию. :)

acidrain
15.10.2006, 10:57
На амиге же происходит вычисление адреса функции (многократное!) вместе с последующим многократным вызовом.

Ты шутишь, да? Скажи, что шутишь? Нет, ну ты ведь ниче не понял? Какое вычесление (тем более многократное?) - мотивируй (видимо кодишь на амми каждый день?)

Vitamin
15.10.2006, 12:43
Ты шутишь, да? Скажи, что шутишь? Нет, ну ты ведь ниче не понял? Какое вычесление (тем более многократное?) - мотивируй (видимо кодишь на амми каждый день?)
Выдвигая данное предположение я основывался на том факте, что libman портирован (более мягкий термин, нежели "содран", да? ;)) с амиги с теми же идеями. А именно, кернель с переходами на функции:
jp func1
jp func2
jp func3
...

А вызов осуществляется следующим образом:
ld hl,(handle)
ld b,function
call l_call
jp c,error

и скажи мне, что же происходит внутри функции l_call? Вероятнее всего, тот код, что я и написал, а именно вычисление адреса и переход на него....

Vitamin
15.10.2006, 12:49
Когда сложность программной системы достигает точки, в которой появляется искушение воспользоваться неявным использованием функциональности, необходимо хорошо владеть ОО анализом. Иначе запросто получится кровавое месиво.
Угу. Пускай реализация ООП в С++ не фонтан (нехватает некоторых вещей и есть избыточность), но это стандарт де-факто. А в процедурном программировании для имитации полиморфизма используют массивы указателей на функции. Явно, а не силами компилятора.


3. GUI в BGE.
Не знаю как другие примеры, но этот к примерам реализации полиморфизма можно отнести с такой же вероятностью, как и ВСЕ плагины для других программ, а также... скомпилированные музыкальные модули! %)


Обычно func index для каждой конкретной точки вызова это константа.
Можно выполнить constant propagation.
Гм. Не подумал даже про это дело, ориентировался на ассемблер и охватывающую функциональность. В случае распространения констант, конечно все получается весьма и весьма изящно и красиво. Respect!

Shaos
15.10.2006, 15:28
Выдвигая данное предположение я основывался на том факте, что libman портирован (более мягкий термин, нежели "содран", да? ;)) с амиги с теми же идеями. А именно, кернель с переходами на функции:
jp func1
jp func2
jp func3
...

А вызов осуществляется следующим образом:
ld hl,(handle)
ld b,function
call l_call
jp c,error

и скажи мне, что же происходит внутри функции l_call? Вероятнее всего, тот код, что я и написал, а именно вычисление адреса и переход на него....

Когда я писал либмана, то Амигу в глаза не видел, так что "содрать" не мог :)

Vitamin
15.10.2006, 15:50
Когда я писал либмана, то Амигу в глаза не видел, так что "содрать" не мог
Не говорю что специально. Да и вообще не вижу ничего зазорного в переносе хороших идей с/на спек.
Основываюсь на словах тов.yoko_ono и acidrain, говорящих что это есть "как в амиге".

captain cobalt
15.10.2006, 17:54
Попробуем сформулировать тезисы по результатам темы:

1. Подход библиотек Амиги - это тормоза ООП без преимуществ ООП.
2. Для Speccy лучше всего подход с пропатчиванием CALL клиента.
3. Косвенные переходы следует использовать для полиморфизма.

elf/2
16.10.2006, 10:54
Надо разбираться в ООП. Рекомендую книгу.
видимо мы читали разные книги...


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

Теперь посмотрим на FAR с плагинами. FAR, очевидно, явно загружает их с помощью LoadLibrary. При этом разработчики FAR не знают, что реализовано в плагине. Они лишь надеются что это нечто полезное. Это неявное использование функциональности.

(забавное сочетание: явное использование функциональности - неявная загрузка DLL; неявное использование - явная загрузка)
в моих книгах ООП=наследование+инкапсуля ция+полиморфизм. и соответсвенно "неявный" вызов возможен только для явных потомков. в случае фара этим даже не пахнет.

фар определяет и использует плагины на основании списка функций, это не ООП. это ближе всего к duck typing которая активно используется в новомодных языках (python, ruby)

тогда уж:
#include "stdio.h"
printf(...)
тоже ООП :) такая программа могла быть написана много лет назад, а работает до сих пор с новыми версиямя libc. причем за годы существования проги libc могла поменяться очень сильно включая новую функциональность


ИМХО о пяти пунктах насквозь пропитано духом процедурного программирования. "Чтобы был динамический компоновщик, нужно чтобы сначала была ось". Это не так. ООП даёт механизм преодоления. FAR запросто может использовать плагины, которых не существовало во время его написания.
пять пунктов ничем не пропитано :) я описал те проблемы которые динамическая загрузка библиотек имеет на текущий момент для спека. а уж про то что для динамической компоновки обязательно нужна ось я точно не говорил :) если Вы говорите что ООП данные ограничения/проблемы позволяет обойти то я удовольствием послушаю как

Пусть у нас нет ни оси, ни программ, ни библиотек, есть только динамический компоновщик. Теперь, подсовывая этому компоновщику модули, можно построить хоть ось, хоть программу. Всё что угодно.
вот только объяснение про "сферический компоновщик в вакуме" это не объяснение. это демагогия на мой взгляд. потому что:
1. кто компоновщика будет загружать?
2. кто ему расскажет что нужно грузить?

elf/2
16.10.2006, 10:59
так и хочется запретить книги про ООП :(


1. Подход библиотек Амиги - это тормоза ООП без преимуществ ООП.
где в амижном подходе ооп? где там наследование и инкапсуляция? какие такие тормоза?


3. Косвенные переходы следует использовать для полиморфизма.
какой на*рен полиморфизм на спекке? вызов функции по таблице - это не полиморфизм

ребята, ну давайте не будем бросаться терминами! особенно если они не однозначные и все их понимают по-своему. а уж если ругаем чего-нибудь, то хотя бы с аргументами

elf/2
16.10.2006, 11:09
Вот именно - в отдельной части EXE хранится список ячеек, в которые надо подставить абсолютные адреса этих функций в момент приведения EXE в работоспособный вид (при загрузке), и создание таких списков - штатная функция генераторов кода на пц.
...
Варианты Shaos'а и мой свободны от любой модификации абсолютных адресов вызовов библиотечных функций в user-программе.
перечитайте пожалуйста мое исходное сообщение. EXE не патчится и либа кстати тоже.
1. в заголовке exe файла находится список jmp'ов
2. все call'ы идут на них
3. когда система загрузит exe+dll она исправляет адреса в этих JMP'ах. ни один байт внутри программы не изменяется!

если я плохо объясняю, то посмотрите в MSDN он в отличии от амижных доков находиться в открытом доступе.

более того, если dll без base relocation (т.е. грузиться по фиксированным адресам) то внутри exe все call'ы идут сразу в библиотеку без дополнительного jmp'а. причем все это делает линкер автоматом при сборке программы, руками делать ничего не надо

Vitamin
16.10.2006, 12:43
где в амижном подходе ооп? где там наследование и инкапсуляция? какие такие тормоза?
Имеется в виду, что ООП тормоза, но есть и преимущества, а подход амиги- тормоза (как и в ООП), но нет преимуществ, перевешивающих тормоза.


так и хочется запретить книги про ООП
Не надо %) ООП это хорошо (при правильном использовании конечно).

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

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

captain cobalt
16.10.2006, 13:01
где в амижном подходе ооп? где там наследование и инкапсуляция? какие такие тормоза? Это не ООП. Это только тормоза ООП. Без наследования и инкапсуляции.

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

Те же самые тормоза, что у вызова виртуальной функции.

Но если полиморфизм - это силища ого-го :) , то у Амиги "просто библиотеки". :)

вызов функции по таблице - это не полиморфизм Зато полиморфизм - это (часто и помимо прочего) вызов функции по таблице.

ребята, ну давайте не будем бросаться терминами! особенно если они не однозначные и все их понимают по-своему. а уж если ругаем чего-нибудь, то хотя бы с аргументами Хорошо. Всегда готов. ;)

captain cobalt
16.10.2006, 13:01
в моих книгах ООП=наследование+инкапсуля ция+полиморфизм. Это правильно. Но это всего-лишь определение ООП. Если пользоваться только определением, ничего хорошего не получится.

Если прочитать определение поэзии, то сразу после этого не станут сразу получаться хорошие стихи. :)

Если взять из матанализа определение предела функции в точке, то вычислить даже один предел довольно затруднительно. К счастью, для этого имеются гораздо более сподручные средства, такие как "Правило Лопиталя", "Теорема Коши" и ещё вагон всяких разных, которые напрямую не следуют из определения предела.

Как грамотно писать ООП программы. На этот вопрос нет ответа в книгах типа "ООП=наследование+инкапсуля ция+полиморфизм". Это всё равно что обучать искусству поэзии по принципу: "поэзия - это <...тут определение поэзии...>; вот, например, Пушкин: <...здесь стихи Пушкина...>".

Как же всё-таки проектировать ООП программы? Об этом рассказывается совсем в других книгах. И обсуждается это не скатываясь на определения.

соответсвенно "неявный" вызов возможен только для явных потомков. в случае фара этим даже не пахнет ООП - это неявное использование функциональности.

Неявное использование функциональности - это не всегда ООП. Но оно всегда может быть выражено в ООП. А раз может, то, по мнению членов "секты ООП", оно должно быть выражено именно так. :)

Как же выразить плагины в ООП? Очень просто: все плагины должны наследовать от одного абстрактного класса плагина.

пять пунктов ничем не пропитано :)

если Вы говорите что ООП данные ограничения/проблемы позволяет обойти то я удовольствием послушаю как Всё очено просто: клиенты базового класса могут динамически компоноваться с реализациями производных классов.

вот только объяснение про "сферический компоновщик в вакуме" это не объяснение. это демагогия на мой взгляд. потому что:
1. кто компоновщика будет загружать? Это не имеет значения.

Его можно загрузить из boot.B, его можно прошить в ПЗУ. Много чего можно.

Но коль скоро динамический компоновщик загружен в память, он может сидеть там сколь угодно долго. :) И динамически компоновать сколь угодно много. :)

2. кто ему расскажет что нужно грузить? А это не его дело что-либо грузить. :) Его дело компоновать то что ему дают. :) Откуда загрузилось то что ему дают компоновать - это тоже не его дело. :)

Кто же будет грузить то что надо компоновать? Грузить может, например, #3D13, который всегда доступен.

Но кто же будет говорить #3D13, что надо грузить? Что ж. Придётся написать маленькую программу, которая будет делать это. С пользовательским интерфейсом. И назвать её "файловый менеджер". :) Более того, поскольку есть динамический компоновщик, то можно скомпоноваться с (собственноручно загруженным) драйвером HDD, а затем грузить модули с HDD.

По функциональности уже ОСь получается, хотя казалось бы, динамический компоновщик... ;)

captain cobalt
16.10.2006, 13:13
EXE не патчится и либа кстати тоже. Здесь нужно уточнить, что на x86 команды прямых CALL и JMP - относительные. Относительно счётчика команд. Если код использует внутри себя только такие переходы, то он перемещаем без пропатчивания.

captain cobalt
16.10.2006, 13:41
Если народ хочет поддержать идею, то я жду предложений по расширению функциональность Вот такие предложения:

1. Динамический компоновщик и библиотеки должны оставаться в памяти как можно дольше без лишних повторных загрузок с диска. Тогда и ось сможет "нарасти".

2. Нужен контроль целостности. Например, на основе строки с перечислением аргументов. Если импортированный и экспортированный интерфейс не совпадают, нужно сообщение об ошибке.

3. Нужна единообразная инструментальная поддержка для статической и динамической компоновки. Чтобы из одних и тех же исходников можно было компоновать как динамически так и статически.

4. Нужно составить список библиотек, которые нужны человечеству. С описанием что они должны делать.

Vitamin
16.10.2006, 14:47
Примерно этого я и ждал вот уже 13 страниц %))


1. Динамический компоновщик и библиотеки должны оставаться в памяти как можно дольше без лишних повторных загрузок с диска. Тогда и ось сможет "нарасти".
Я еще не заглядываю в такие далекие дебри как динамическая компоновка. У меня (по смыслу) статически-динамическая: динамическая в смысле что все подгружается при старте, а статическая в смысле что все настраивается за кадром и программа знать не знает что ее собрали из кусочков.


2. Нужен контроль целостности. Например, на основе строки с перечислением аргументов. Если импортированный и экспортированный интерфейс не совпадают, нужно сообщение об ошибке.
Ну простейший контроль само собой- если в собранной программе остались неразрешенными некоторые внешние ссылки, она считается невалидной. Равно как и если есть две и более точки с одним и тем же именем (для универсальности- сигнатурой). Плюс конечно версионный контроль


3. Нужна единообразная инструментальная поддержка для статической и динамической компоновки. Чтобы из одних и тех же исходников можно было компоновать как динамически так и статически.
Это уже тонкости, их реализация осущствляется автоматически при правильном выборе функционала и механизма реализации релокации и интерфейсов.


4. Нужно составить список библиотек, которые нужны человечеству. С описанием что они должны делать.
Ну простейшее- математика, графика, дисковые операции. А в дальнейшем- каждый может писать свои и выкладывать их.

elf/2
16.10.2006, 15:01
По функциональности уже ОСь получается, хотя казалось бы, динамический компоновщик...
вот и я о том же :) либо компоновщик - часть "оси", либо статически слинкован с программой

а про ООП в этом треде надо завязывать, imho. пока нет языка с явной поддержкой по крайней мере...

да и вообще сравнивать ООП с библиотеками - не корректно. т.к. лежат они на совершенно разных уровнях.

одна беда в этом треде: слишком все эмоционально, и надо бы его уже на два-три делить
1. статическая линковка из объектников (Витамин предложил): как это сделать на спекки оптимально
2. динамическая линковка: изложить и сравнить существующие подходы (амми/libman/Win/Lin/etc.) и в результате выбрать/синтезировать то что для спека лучше подходит
3. ооп и иже с ним (лучше сразу во флейм)

maximk
16.10.2006, 16:13
Ребят, а на самом деле - стоит ли оно того?

Посмотрим еще раз на плюсы:
1) экономия места. Но кого оно волнует из эмуляторщиков (а их большинство)? Да и реальщики стараются подрубить винт или флешку.
2) исправление ошибки в библиотеке устраняет оную во всех зависимых программах.

Но как правильно было замечено, (2) одновременно ведет и к гораздо бОльшей проблеме, то что в винде было названо DLL-hell. Ладно там ошибку исправить, а как быть, когда в результате эволюции наступает этап, когда требуется изменение интерфейса функции? Ресурсы спектрума уж очень скромны, чтобы решать такие задачи, где даже у старших братье все до сих пор не все гладко.

И еще. В спектрум-среде за все это время как-то не сложилась практика использования общих библиотек, думаете когда сообщество стало гораздо менее многочисленным есть еще шансы?

Частично проблемы общих библиотек решаются с появление нормальной ОСи. Ведь тогда ввод-вывод уже будет поддержан ядром, а это основное, где могут присутствовать обшие куски. Второе - UI-core - но его почти всегда каждый предпочитает делать по-своему.

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

captain cobalt
16.10.2006, 16:48
Я еще не заглядываю в такие далекие дебри как динамическая компоновка. У меня (по смыслу) статически-динамическая: динамическая в смысле что все подгружается при старте, а статическая в смысле что все настраивается за кадром и программа знать не знает что ее собрали из кусочков. Как только что показано, загрузка и компоновка - это разные вещи.
Сборка в момент загрузки - это динамическая компоновка.

Держать библиотеки в памяти наиболее полезно для разработки.

Сейчас для сборки используются include. В однотекстовых ассемблерах при каждой сборке происходит елозенье по диску. В многотекстовых, когда всё в памяти, всё равно имеются тормоза с компиляцией. Если же всё лежит в памяти готовое к употреблению, нужно лишь при компиляции прилинковать один разрабатываемый модуль.

Ну простейший контроль само собой- если в собранной программе остались неразрешенными некоторые внешние ссылки, она считается невалидной. Равно как и если есть две и более точки с одним и тем же именем (для универсальности- сигнатурой). Вот.
Сигнатура это хорошо и обязательно.

Это уже тонкости, их реализация осущствляется автоматически при правильном выборе функционала и механизма реализации релокации и интерфейсов. Проблема такая.
Есть "старая добрая статическая" сборка через include. Есть "новая крутая динамическая". :)

Программист смотрит. Если инструментарий отличается, нужно выбирать что использовать. Для старого способа уже есть свой наработанный код. Для нового способа надо переписывать, переделывать почти с нуля. Многие не смогут разобраться в своих собственных старых ассемблерных исходниках. :)

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

Ну простейшее- математика, графика, дисковые операции. А в дальнейшем- каждый может писать свои и выкладывать их. Нужно поточнее списочек.

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

да и вообще сравнивать ООП с библиотеками - не корректно. т.к. лежат они на совершенно разных уровнях. А бывают "библиотеки классов"? :)

elf/2
16.10.2006, 17:08
Сигнатура это хорошо и обязательно.
какая-такая проверка сигнатур при динамической линковке? этого даже в винде, где ресурсов много, не делают. а тем более откуда сигнатуры брать в случае ассемблера?

captain cobalt
16.10.2006, 17:18
Но как правильно было замечено, (2) одновременно ведет и к гораздо бОльшей проблеме, то что в винде было названо DLL-hell. Ладно там ошибку исправить, а как быть, когда в результате эволюции наступает этап, когда требуется изменение интерфейса функции? Ресурсы спектрума уж очень скромны, чтобы решать такие задачи, где даже у старших братье все до сих пор не все гладко. Именно поэтому нужен контроль интерфейса не просто по имени, а по сигнатуре.

На заскоки старших братьев конкретно от Microsoft можно не обращать внимания. :)

И еще. В спектрум-среде за все это время как-то не сложилась практика использования общих библиотек, думаете когда сообщество стало гораздо менее многочисленным есть еще шансы?

Частично проблемы общих библиотек решаются с появление нормальной ОСи. Ведь тогда ввод-вывод уже будет поддержан ядром, а это основное, где могут присутствовать обшие куски. Второе - UI-core - но его почти всегда каждый предпочитает делать по-своему. Это уже следующий вопрос.

Нужны не просто библиотеки. Нужен framework. Эдакий каркас с ячейками, в которые можно вставлять свой код.

Программирование становится намного комфортнее.

Но здесь сейчас опять у кого-нибудь случится истерика.

captain cobalt
16.10.2006, 17:25
какая-такая проверка сигнатур при динамической линковке? этого даже в винде, где ресурсов много, не делают. Поправочка.
Не делали.
Теперь, когда DLL hell доканал, придумали новые чудеса техники.

а тем более откуда сигнатуры брать в случае ассемблера? Прописывать вручную.

elf/2
16.10.2006, 17:37
Поправочка. Не делали. Теперь, когда DLL hell доканал, придумали новые чудеса техники.
я слышал что dll hell был связан с несовместимостью версий библиотек... но тем неменее чудеса техники в студию. как теперь с этим борються? уж не предагается ли reflection на спекке делать?



а тем более откуда сигнатуры брать в случае ассемблера?
Прописывать вручную.
фтопку! слишком много ошибок будет и главное не понятно как их потом проверять. тоже руками :) ?

Vitamin
16.10.2006, 17:38
Частично проблемы общих библиотек решаются с появление нормальной ОСи. Ведь тогда ввод-вывод уже будет поддержан ядром, а это основное, где могут присутствовать обшие куски. Второе - UI-core - но его почти всегда каждый предпочитает делать по-своему.
А почему предпочитает? Потому что "кого хочу- не знаю, кого знаю- не хочу". Я вот тоже свой UI писал по мотивам SupremeGUI от DT. Была б она открыта (в то время)- использовал бы ее и все... А будет выбор- будет использование.


Имхо, гибкий инстурмент подключения библиотек во время компоновки был бы более уместен. Кстати, в CP/M такое было. В том числе там можно было подключить из бибилиотеки к модулю прямо конкретную функцию, а не всю либу.
У меня по этому поводу одна идея- проводить вырезание только нужных функций. Но это требует ресурсов и может быть применено только при окончательной сборке бинарника (не runtime).
А про CP/M (точнее, реализацию) поподробнее можно?


Держать библиотеки в памяти наиболее полезно для разработки.
Это уже интимные проблемы компилятора. Будет кешировать- будут в памяти, не будет кешировать- будет елозить по диску.


какая-такая проверка сигнатур при динамической линковке? этого даже в винде, где ресурсов много, не делают. а тем более откуда сигнатуры брать в случае ассемблера?
Хранить внутри файла библиотеки. Если жалко места на строку вида
memcpy[сигнатура в бешеном формате], то можно делать хеширование в 3-4 байта и не мучаться. Само собой, линковщик должен это учитывать

captain cobalt
16.10.2006, 18:03
я слышал что dll hell был связан с несовместимостью версий библиотек... но тем неменее чудеса техники в студию. как теперь с этим борються? уж не предагается ли reflection на спекке делать? Например в дотнете сборки контролируются по номеру версии.

На спеке предлагается контроль сигнатур по хэшам.

фтопку! слишком много ошибок будет и главное не понятно как их потом проверять. тоже руками :) ? Есть предложение совместить это с системой автодокументирования исходника.

Из исходника компилируется отдельно объектный код, отдельно - документация.

Проверочные хэши генерируются из ключевых кусков документации.

Идея в том, что по неправильной документации невозможно написать правильный клиентский код. :)

Далее работает правило: "если документация, по которой программист писал клиентский код не совпадает с текущей документацией - компоновка не происходит". :)

Это уже интимные проблемы компилятора. Будет кешировать- будут в памяти, не будет кешировать- будет елозить по диску. Ну так лучше, если они будут сидеть скомпонованные друг с другом. Сидеть и не двигаться с места. Новый код будет помещаться в свободную память и прикомпоновываться к ним.

acidrain
16.10.2006, 18:05
говорящих что это есть "как в амиге".
Я не говорил, что либман - есть как в амиге. Это полностью творение рук Шаоса. Как он его реализовал - не вдавался. А вот в начале (первый толчек к созданию) я поучаствовал. Но это не говорит о том, что это копия с амиги.
По поводу переходов - на амиге никаких вычислений, догадайся почему 8)

elf/2
16.10.2006, 18:19
Например в дотнете сборки контролируются по номеру версии.
На спеке предлагается контроль сигнатур по хэшам


Есть предложение совместить это с системой автодокументирования исходника. Из исходника компилируется отдельно объектный код, отдельно - документация.
Проверочные хэши генерируются из ключевых кусков документации.


Хранить внутри файла библиотеки. Если жалко места на строку вида
memcpy[сигнатура в бешеном формате], то можно делать хеширование в 3-4 байта и не мучаться. Само собой, линковщик должен это учитывать

даже комментировать не хочется :( если все это про динамические библиотеки.
1. генерация/проверка сигнатур должна делаться автоматически. на асме типов нет, и параметры передаются как бог на душу положит. значит автомат идет лесом
2. кто видел нормально комментированый код на спеке?
3. проверка будет жрать кучу времени... а вы только что плющили амижников по поводу "тормозов аналогичных ООП"

captain cobalt
16.10.2006, 18:21
я слышал что dll hell был связан с несовместимостью версий библиотек... но тем неменее чудеса техники в студию. как теперь с этим борються? Вот более подробное изложение: ;)

История программных революций от Microsoft, вкратце: Сначала были Windows API и DLL Hell. Революцией №1 было DDE — помните, как ссылки позволили нам создавать статусные строки, отражающие текущую цену акций Microsoft? Примерно тогда же Microsoft создала ресурс VERSION INFO, исключающий DLL Hell. Но другая группа в Microsoft нашла в DDE фатальный недостаток — его писали не они!

Для решения этой проблемы они создали OLE (похожее на DDE, но другое), и я наивно вспоминаю докладчика на Microsoft-овской конференции, говорящего, что скоро Windows API перепишут как OLE API, и каждый элемент на экране будет ОСХ-ом. В OLE появились интерфейсы, исключающие DLL Hell. Помните болезнь с названием "по месту", при которой мы мечтали встроить все свои приложения в один (возможно, очень большой) документ Word? Где-то в то же время Microsoft уверовала в религию С++, возникла MFC решившая все наши проблемы еще раз.

Но OLE не собиралась, сложа руки смотреть на это, поэтому оно заново родилось под именем COM, и мы внезапно поняли, что OLE (или это было DDE?) будет всегда — и даже включает тщательно разработанную систему версий компонентов, исключающую DLL Hell. В это время группа отступников внутри Microsoft обнаружила в MFC фатальный недостаток — его писали не они! Они немедленно исправили этот недочет, создав ATL, который как MFC, но другой, и попытались спрятать все замечательные вещи, которым так упорно старалась обучить нас группа COM. Это заставило группу COM (или это было OLE?) переименоваться в ActiveX и выпустить около тонны новых интерфейсов (включая интерфейсы контроля версий, исключающие DLL Hell), а заодно возможность сделать весь код загружаемым через браузеры, прямо вместе с определяемыми пользователем вирусами (назло этим гадам из ATL!).

Группа операционных систем громким криком, как забытый средний ребенок, потребовала внимания, сказав, что нам следует готовиться к Cairo, некой таинственной хреновине, которую никогда не могли даже толком описать, не то, что выпустить. К их чести, следует сказать, что они не представляли концепции "System File Protection", исключающей DLL Hell. Но тут некая группа в Microsoft нашла фатальный недостаток в Java — её писали не они! Это было исправлено созданием то ли J, то ли Jole, а может, и ActiveJ (если честно, я просто не помню), точно такого же как Java, но другого. Это было круто, но Sun засудило Microsoft по какому-то дряхлому закону. Это была явная попытка задушить право Microsoft выпускать такие же продукты, как у других, но другие.

Помните менеджера по J/Jole/ActiveJ, стучащего по столу туфлей и говорящего, что Microsoft никогда не бросит этот продукт? Глупец! Все это означало только одно — недостаток внимания к группе ActiveX (или это был COM?). Эта невероятно жизнерадостная толпа вернулась с COM+ и MTS наперевес (может, это стоило назвать ActiveX+?). Непонятно почему к MTS не приставили "COM" или "Active" или "X" или "+" — они меня просто потрясли этим! Они также грозились добавить + ко всем модным тогда выражениям. Примерно тогда же кое-кто начал вопить про "Windows DNA" (почему не DINA) и "Windows Washboard", и вопил некоторое время, но все это почило раньше, чем все поняли, что это было.

К этому моменту Microsoft уже несколько лет с нарастающей тревогой наблюдала за интернет. Недавно они пришли к пониманию, что у Интернет есть фатальный недостаток: ну, вы поняли. И это приводит нас к текущему моменту и технологии .NET (произносится как "doughnut (пончик по-нашему)", но по-другому), похожей на Интернет, но с большим количеством пресс- релизов. Главное, что нужно очень четко понимать — .NET исключает DLL Hell.

В .NET входит новый язык, C#, (выясняется, что в Active++ Jspresso был фатальный недостаток, от которого он и помер). .NET включает виртуальную машину, которую будут использовать все языки (видимо, из-за фатальных недостатков в процессорах Интел). .NET включает единую систему защиты (есть все-таки фатальный недостаток в хранении паролей не на серверах Microsoft). Реально проще перечислить вещи, которых .NET не включает. .NET наверняка революционно изменит Windows-программирование... примерно на год.

captain cobalt
16.10.2006, 18:53
генерация/проверка сигнатур должна делаться автоматически. Да.

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

параметры передаются как бог на душу положит Передача параметров описывается в документации. Из этих кусков документации генерируются проверочные хэши.

проверка будет жрать кучу времени... Для каждого экспортированного-импортированного символа сравнить два числа.

Никаких накладных расходов во время выполнения.

значит автомат идет лесом Значит автомат не идёт лесом.

на асме типов нет Плохо.

Есть два основных выхода:
1. Подсмотреть ООП на ПЦ (в TASM и т. п.).
2. Использовать typed assembly language, "типизированный ассемблер", сокращённо TAL. Идея в принципе прикручиваема к Z80. Но это - как раз сильно отдалённое будущее, о котором будем говорить гораздо позже. Ссылки здесь (http://www.wasm.ru/forum/viewtopic.php?id=8338).

Vitamin
16.10.2006, 19:00
По поводу переходов - на амиге никаких вычислений, догадайся почему 8)
И что с того? От осознавания мною того факта, что на амиге не делаются вычисления, на спектруме они не исчезнут. Так что смотреть на все возможные варианты создания релоцируемых бинарников надо через призму возможностей спектрума.
ЗЫ. Доки получил?


1. генерация/проверка сигнатур должна делаться автоматически. на асме типов нет, и параметры передаются как бог на душу положит. значит автомат идет лесом
Откуда компилятор должен брать исходные данны для генерации сигнатуры? Из астрала чтоли? :) Ручками прописать. А типы на асме есть, стыдно говорить что нету! %) И передача параметров (распределение регистров) прекрасно можно описать в сигнатуре. В связи с этим отпадает необходимость тянуть мегабайт документации с описанием в какие регистры надо засовывать параметры и постоянно в нее шариться.
ЗЫ. Чета идея генерации хеша по документации не вставляет- а ну запятую переставишь в описании и все, новая версия?


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

Кстати я тут подумал по поводу применения полиморфизма для уменьшения размера бинарников.
Предположим, мы имеем абстрактную библиотеку GUI с кучей разных типов виджетов. Как это обычно делается? Некоторая структурка в памяти, у которой есть числовой идентификатор. А гдето в функции вывода (создания, удаления и т.д.) висит здоровое такое ветвление с кучей проверок и кучей переходов на разные функции. Что мы имеем в итоге? Что придется тянуть всю библиотеку, даже если мы используем всего один-два вида виджета. Если библиотека распространяется в виде исходников, можно применить ключи для включения/отключения некоторых возможностей (я так у себя делал). В бинарнике такое, ясное дело, не получится.
Зато если мы имеем полиморфизм, мы полностью отделяем реализацию от типа и имеем возможность неограниченного расширения путем наследования. При этом из бинарника можно будет вырезать ненужный (сиречь неиспользуемый) код. Правда проверка на используемость получается очень и очень ресурсоемкая- все портят таблицы виртуальных функций, которые по идее уже прошиты в бинарнике, но явно нигде не светятся...

captain cobalt
16.10.2006, 19:33
Чета идея генерации хеша по документации не вставляет- а ну запятую переставишь в описании и все, новая версия? Не по всей документации, а только по "ключевым кускам".

Сигнатура - это всё равно неотъемлемая часть документации.
Нужно лишь её определённым образом отмечать, чтобы хэш считался только от неё.

Кстати я тут подумал по поводу применения полиморфизма для уменьшения размера бинарников.
Предположим, мы имеем абстрактную библиотеку GUI с кучей разных типов виджетов. Можно каждый виджет поместить в свой модуль.
Тогда в импорте можно прописать только те модули, которые используются. :)

elf/2
16.10.2006, 19:38
И передача параметров (распределение регистров) прекрасно можно описать в сигнатуре. В связи с этим отпадает необходимость тянуть мегабайт документации с описанием в какие регистры надо засовывать параметры и постоянно в нее шариться.
проверка сигнатур нормально работает только на этапе компиляции.

в динамике у нас есть только два имени и все. в этом случае я не вижу чем имя функции memcpy хуже memcpy_VI#43543 (написанной руками) с точки зрения безопасности и отсутствия dll hell. и главное никто проверить уже не сможет что мы ее зовем правильно просто сравнивая имена.

а нормальная проверка сигнатуры т.е. парсинг и сравнение пока не понятно с чем точно кучу времени съест.

Vitamin
16.10.2006, 20:20
Сигнатура - это всё равно неотъемлемая часть документации.
Нужно лишь её определённым образом отмечать, чтобы хэш считался только от неё.
Зачем сюда вообще прилеплять документацию? Да ни в жизни библиотеки не различались по версии описания.


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


проверка сигнатур нормально работает только на этапе компиляции.
Чего???? Как раз только на этапе линковки. Чтобы знать что и с чем склеивать.


в динамике у нас есть только два имени и все. в этом случае я не вижу чем имя функции memcpy хуже memcpy_VI#43543 (написанной руками) с точки зрения безопасности и отсутствия dll hell. и главное никто проверить уже не сможет что мы ее зовем правильно просто сравнивая имена.
С точки зрения линкера, все эти имена равнозначны. Но для пущей унификации весьма и весьма желательно закодировать в сигнатуре входные параметры и возвращаемый тип. Убиваем сразу несколько зайцев- можем свободно иметь перегружаемые функции, отпадает необходимость постоянно смотреть в документацию дабы вспомнить в каких регистрах параметры передаются и получаем зачин на использование ЯВУ (а компиляторы именно так кодируют названия функций)

captain cobalt
16.10.2006, 20:26
в этом случае я не вижу чем имя функции memcpy хуже memcpy_VI#43543 memcpy - это имя. VI#43543 - это то самое проверочное магическое число. Оно остаётся "за кулисами". В клиентском коде используется только memcpy. VI#43543 просто копируется в клиентский модуль с объектным кодом во время компиляции. Во время динамической компоновки они просто проверяются на равенство.

Предполагается, что автор memcpy изменив интерфейс (или внеся иную несовместимость) изменит сигнатуру. Несовместимые модули не будут компоноваться. Если автор забудет изменить сигнатуру, то вспомнит когда у него что-нибудь сломается. Если у него ничего не сломается, ему сообщит кто-нибудь, у кого сломается. Если автор забил на спек, проблема может быть опубликована.

Смысл в том, чтобы несовместимость обнаруживалась легче.
Вместо того чтобы "непонятная чертовщина" накапливалась до тех пор пока не получила звание "глюкало мастдайное". :)

captain cobalt
16.10.2006, 20:42
Зачем сюда вообще прилеплять документацию? Да ни в жизни библиотеки не различались по версии описания. Сигнатура - это часть документации.
Документация всё равно понадобится.
Поэтому - чтобы не плодить сущностей.

Чего???? Как раз только на этапе линковки. Чтобы знать что и с чем склеивать. На самом деле в языках высокого уровня она действительно работает во время компиляции. Проверяется, что передаётся правильное количество аргументов правильных типов.

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

Vitamin
16.10.2006, 21:54
Сигнатура - это часть документации.
Неа. Переводим документацию на другой язык получаем другую библиотеку? Типа был Паскаль, получили 1С? :)))


Документация всё равно понадобится.
ППКС


Поэтому - чтобы не плодить сущностей.
Сущности и не будут плодиться.


На самом деле в языках высокого уровня она действительно работает во время компиляции. Проверяется, что передаётся правильное количество аргументов правильных типов.
Насколько я знаю, для создания имен используются описания интерфейсов (для С это заголовочные файлы). А вот сверка уже потом на этапе линковки.


А в ассемблере. Если мы забыли загрузить аргумент в регистр, и в регистре мусор от предыдущего использования - компилятор ничего не скажет.
А это уже везде. Вне зависимости от платформы, наличия или отсутствия ОС.

Я тут наброски делал по поводу организации сигнатуры. Часть подсмотрел, часть придумал сам. Вот что получилось.

Символьное имя точки.
Символьное имя может содержать в себе дополнительную информа-
цию о сигнатуре, типах параметров и возвращаемом значении (в
квадратных скобках указаны необязательные параметры):
PointName[@signature[(parameters)[#out_type(params_type)]]],\0

signature определяет сигнатуру точки (флаги в символьном экви-
валенте и типы входных параметров для точки-функции в скобках):
Uname;- пользовательский тип name
[type- указатель на тип type
{type- константный указатель на тип type
число скобок определяет вложенность, итоговая константность
определяется по типу последней скобки.
V- void
C- char
I- int
L- long
F- float
c- CARRY
z- ZERO
y- CARRY&ZERO
f- function
B- byte
W- word
D- dword
E- double

Типы c,z и y применяются только для точек-функций.
Также для точки-функции возможно уточнение типа передавае-
мых и возвращаемых значений после знака #. out_type определяет,
как возвращается значение, params_type определяют способ пере-
дачи параметров. Если уточнения нет, то параметры передаются
согласно компилятору (в случае ЯВУ). Следующие обозначения для
различных способов передачи данных:
a- регистр А, 8 бит
b- регистр B, 8 бит
c- регистр C, 8 бит
d- регистр D, 8 бит
e- регистр E, 8 бит
f- регистр F, 2 бита (ZERO & CARRY)
B- регистр BC, 16 бит
H- регистр HL, 16 бит
L- регистр HLDE, 32 бита (HL- старшие биты)
D- регистр DE, 16 бит
E- регистр DEHL, 32 бита (DE- старшие биты)
X- регистр IX, 16 бит
Y- регистр IY, 16 бит
m<name>- в области памяти с именем name.
sN- по смещению в стеке в N байт от SP на момент старта про-
цедуры. Для доступа к переменным может использоваться сле-
дующий код:

PointName:
ld iy,-2
add iy,sp
...
ld a,(iy+N)
...
ld l,(iy+N)
ld h,(iy+N+1)
...

Пример кодирования сигнатуры экспортируемых точек:
int integerVariable; => integerVariable@I,\0
char* strcpy(char* dst, const char* src); => strcpy@[C([C{C),\0
или, при спецификации регистров (in=de,hl, out=de):
strcpy@[C([C{C)#D(DH),\0
void myfunc(mytype** ptr); => myfunc@V([[Umytype),\0

captain cobalt
16.10.2006, 22:38
m<name>- в области памяти с именем name.
sN- по смещению в стеке в N байт от SP на момент старта про-
цедуры. Ещё нужны inline константные аргументы, размещаемые в коде типа

CALL target
DB 5
DW #7ffd
; сюда возврат

,\0 Что это?

Неа. Переводим документацию на другой язык получаем другую библиотеку? Типа был Паскаль, получили 1С? Рассмотрим на примере

;; @sig strcpy@[C([C{C)#D(DH)
;; Копирование строки
;; @arg HL - источник
;; @arg DE - приёмник
;; @ret DE - результат

strcpy LD A,(HL) ; пошла сама процедура Две точки с запятой - это комментарий документатора.

С собаки начинаются тэги документатора.

@sig - объявление сигнатуры, которое хэшируется и попадает в модуль с объектным кодом.

Остальное попадает в документацию. Без тэга - просто переписывается в документацию. @arg и @ret - оформляется в документации соответствующими разделами.

Ну разве не заглядение? ;)

Vitamin
16.10.2006, 22:45
Ещё нужны inline константные аргументы, размещаемые в коде типа

CALL target
DB 5
DW #7ffd
; сюда возврат
сложна имхо реализация... смещения только последовательно и плясать от адреса возврата


Что это?
завершающий 0. сишный синтаксис приплел %)


Две точки с запятой - это комментарий документатора.

С собаки начинаются тэги документатора.

@sig - объявление сигнатуры, которое хэшируется и попадает в модуль с объектным кодом.

Остальное попадает в документацию. Без тэга - просто переписывается в документацию. @arg и @ret - оформляется в документации соответствующими разделами.

Ну разве не заглядение?
У мя не так, у мя документация отдельно, директивы компилятора отдельно. Типа:

__PUBLIC "strcpy@[C([C{C)#D(DH)",FUNCTION
ld a,(hl)
...

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

GriV
16.10.2006, 23:29
пересилил я себя, в который раз причём

Я витамина сразу понял а вот основная масса участников видимо не прониклась духом идеи - как говорят софисты "прежде чем отергать идею, надо проникнуть её духом"

Витамин спросил - какова вообще идея?
Я считаю что идея отличная, и ставлю за идею 5 баллов.

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

Мне кажется основная масса непоняток выходит из того, что витамин недостаточно внятно объяснил что это даст. А я попытаюсь это сделать.

Вот такая общая мысль.
Каждый из нас сталкивался при написании своих программ с тем, что надо рисовать 1 единственный символ в заданном знакоместе из заданного шрифта (расположенного в памяти). Стандартное RST 8 кажется по-моему только на заре программирования использовали - каждый сейчас пользует для этого свой код. Даже в случае, если надо рисовать символ 8x8 точек (что справедливо далеко не всегда). Вот первый претендент - процедура прорисовки символов. (здесь не торопитесь писать "опровержение", потерпите и дочитатайте тред до конца). Вызов - в программе - на внешнюю точку Call Scr.PrintChar8x8 (первая часть имени функции обозначает его модуль - модуль Scr)

Каждый из нас сталкивался с тем, что отсутствует эффективная процедура работы с диском (опять же стандартная #3D13 слишком медленнная, и даже имеющиеся в ней возможности порой значительно ограничены). Тут уж я исключаю такого рода проблемы как поддержка (полная) жёсткого диска, работа с расширенной файловой системой TRDOS Directory System и т.д. Поэтому второй претендет - бинарник для работы с носителями, в том числе с файлами. Вызов Disc.FileRead, Disc.SectorRead, Disc.SectorWrite. Кстати не факт, что даже те процедуры что сейчас есть для скачивания работают хорошо - я вот специально для себя писал очень хитрый дискожуйный процедур, который работает не посекторно а потреково, что уменьшает время решения разрешаемых ошибок чтения и уменьшает "головобуйство" дисководов, экономя их ресурс в том числе, но опять же не про это речь. Модуль - Disc.

Модуль опроса клавиатуры.
Не секрет, что клавиатурный менеджер висящий на прерываниях спекка опять же оставляет желать лучшего - нет буферизации нажатых символов, нет возможности (через него) определить нажатие функциональных клавиш - таких как SymShift, CapsShift; русскоязычная поддержка это вообще из области фантастики. KB.ReadKey - читает клавишу нажатую пользователем. KB.Clear - очищает буфер. Модуль соответственно - KB.

Модуль рисования всеразличных рамок - Window. Window.Show - прорисовывает окошко. Тут даже может быть целая система, учитывающая взаимозакрывания окошек (т.е. когда окошко одно частично закрыто другим, а потом это заднее окошко всплывает).

Модуль арифметических операций Arithm - работает с быстрой целочисленной арифметикой (скорость калькулятора ПЗУ SOS оставляет желать лучшего, хотя функционал там конечно богатый). Arithm.16mul16 - перемножает два 16битных числа. Arithm.16div16 - делает одно 16разрядное на другое.

Модуль работы с памятью - RAM. RAM.ChangePh - смена страницы памяти на заданную физическую. RAM.ChangeLog - смена страницы памяти на заданную логическую.

И вот, я хочу написать бут, хочу написать текстовый редактор, хочу написать вьюер, хочу написать игрушку. Что из этих процедур я буду использовать? Правильно - все из них. И тем не менее, в существующей среде каждая из программ использует свой воз и тележку - где хранится это всё добро, и мало того - по причине закрытости исходов, нежелания автора заниматься программой и т.д. и т.п. в программах есть глюки, которые (90%) являются следствием криво написанных перечисленных процедур. Т.е. битком забитый диск программами спекковский диск де факто повторяет себя почти на 90%. Кроме того, часто указанные процедуры цепляются к тексту в виде некоего дополнения к каждой из запускаемых программ - в итоге и без того ограниченное количество допустимых файл-ячеек в ТРДОС используется малоэффективно.

И теперь смотрим как это может быть - на диске лежит 1 pak файл, лежит 1 boot.B и кусочек кода к нему и лежат куча стартеров - файлов скажем с расширением R (взято произвольно, кстати они тоже могут быть в виде одного файла, и вообще здесь файловая структура не так критична). Эти стартеры могут быть и бейсик программами и просто кодом - это не так важно. Важно, что boot.b загрузит при старте линковщик (или компилятор если угодно), который будет уже работать с лежащими в pak файле указанными модулями.
Хочется подчеркнуть такой немаловажный с моей точки зрения момент - модули фактически являются законченным машинным под Z80 кодом с той лишь разницей, что он сопровождается заголовком релокации для того, чтобы можно было склеить эти модули с головной программой. Впрочем, лучше почитать документацию к модулям и станет понятно что обвинения в писюканстве и амижстве здесь бессмысленные.
И вот, запускаю я свой излюбленный вьюер - и что же? фактически, загрузится МОЯ логика реализованная в коде Z80 - мой код (назову это индивидуальный код) - т.е. только то, что в общем то и надо было написать для того чтобы куча библиотек превратилась в вьюер [основная масса существующего программного зоопарка несовершенна по причинами того, что кодер реализовав свою логику, которая на самом деле является изюминкой программы должен ещё и написать процедуры для отработки указанных действий - работы с дисками, клавиатурой, арифсетика, память и т.д.] - код будет просто дёргать нужные функции и я не буду задумываться о реализации универсального драйвера памяти (кроме случая когда он будет для меня слишком медленный, но это около 1% случаев всего кодописания), я не буду задумываться куда мне обратиться за опросом клавиатуры, я не буду задумываться даже на каком устройстве я сейчас работаю - потому что драйвер уже это сделает, потому что он включен в программу - ну и т.д.

Теперь, нажал я резет. Надоел мне вьюер, я захотел текст понабирать - и всё то же самое - загрузился только МОЙ индивидуальный код и все остальные модули подхватились сами.

Кстати тут очень интересный вариант, что модули будут лежать даже не на самом диске, а скажем на ЖД, или например во втором дисководе будет лежать диск с модулями - т.е. даже отпадёт необходимость на конечный диск писать библиотеки.

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

Напоследок хочу сравнить два подхода - которые как мне кажется в некотором смысле конкурирующие - 1) когда имеются ИСХОДНИКИ всех используемых процедур и в процессе компиляции всё собирается в один конечный файл 2) когда имеется модульная структура и фактически компилируется только индивидуальный код.

1) возможность расширения 100% за счёт стороннего кода; возможность подмены исходных возможно глючных библиотек - только при перекомпиляции всего кода; количество необходимых файлов (в килобайтах и в штуках) - большое
2) возможность расширения - отсутствует, это готовый код - только при перекомпиляции; возможность подмены библиотек - 100% за счёт модульной организации; количество необходимых файлоы (в штуках и килобайтах) - невелико.

captain cobalt
16.10.2006, 23:32
сложна имхо реализация... смещения только последовательно и плясать от адреса возврата Имеется ввиду, нужен синтаксис для сигнатуры.

Технология использования таких аргументов хорошо отработана. Например:

EX (SP),HL
LD A,(HL)
INC HL
LD C,(HL)
INC HL
LD B,(HL)
INC HL
EX (SP),HL Даже более привлекательно, чем ковыряться в стеке через индексные регистры.

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

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

Код на макросах ALASM зависит от ALASM, который не всем нравится. И лишь макросами всё равно не выкрутиться. Например, хотелось бы выражения от импортированных символов, которые сохранялись бы в компилированных модулях и вычислялись во время компоновки (опять вспоминаем обратную польскую запись в iS-DOS).

captain cobalt
16.10.2006, 23:51
RAM.ChangeLog - смена страницы памяти на заданную логическую Не очень удачное название функции.

Список модулей хороший.

Теперь, нажал я резет. Надоел мне вьюер, я захотел текст понабирать - и всё то же самое - загрузился только МОЙ индивидуальный код и все остальные модули подхватились сами. Ну вот опять.

Не надо нажимать RESET.

Надо выйти из вьюера. Динамический компоновщик и модули останутся в памяти.

Загрузить текстовый редактор. Он будет использовать модули уже находящиеся в памяти.

Есть что-нибудь против такого подхода?

2) возможность расширения - отсутствует, это готовый код - только при перекомпиляции; возможность подмены библиотек - 100% за счёт модульной организации; Возможность расширения - за счёт добавления модулей.

GriV
17.10.2006, 00:02
Ну вот опять.

Не надо нажимать RESET.

Надо выйти из вьюера. Динамический компоновщик и модули останутся в памяти.

Загрузить текстовый редактор. Он будет использовать модули уже находящиеся в памяти.

Есть что-нибудь против такого подхода?

Уже использованный один раз модули надо будет подгружать ещё раз или держать отдельную партию где то в памяти. Фишка в том, что уже "вставленные" в программу модули не получится отделить от программы - это такое свойство модульной структуры.
Всё-таки я тебе рекомендую посмотреть и разобраться досконально со структурой модулей. С моей точки зрения такой подход совместим только с отдельно фунциклирующей ОСью, а никак не самостоятельные приложения.
Впрочем здесь нет ограничений на решения, ежели boot.b будет настолько "умным" то возможен и такой вариант - он грузит контейнер модуля в вырхнюю память, а в нижнюю копирует его присоединяет к программе и поехали...


Возможность расширения - за счёт добавления модулей.

Ты здесь чего-то недопонимаешь, опять же наверное из-за модулей. Ты можешь расширять программу только когда ты её пишешь - модули же уже написанные и откомпилированные программы (пусть и в особом контейнере). Чтобы чего-нибудь там расширить придётся грузить ассемблер (или ЯВУ если угодно) править программу и включать в неё указание на эти модули. Технология динамической подгрузки здесь не канает, потому что уже запущенное приложение не должно нуждаться ни в одной библиотеке и работать самостоятельно.
Если же утверждается обратное, то ещё раз - это уже будет не бут-линковщик и целая ОСь.

GriV
17.10.2006, 00:04
2Vitamin> какие уже (в настоящее время) есть вещи так или иначе связанные с модульной организацией (полный список, включая документацию). Что нужно чтобы сие стало "скорее живым, нежели мёртвым"?

yoko_ono
17.10.2006, 00:50
Попробуем сформулировать тезисы по результатам темы:

1. Подход библиотек Амиги - это тормоза ООП без преимуществ ООП.


Уважаемый captain cobalt, скажите, вы вживую видели 'подход библиотек Амиги'? Я что-то сомневаюсь... Вы вон давеча ажно драйвер памяти аласма записали в ООП или куда там. Признайтесь, вы даже его в глаза не видели?!

yoko_ono
17.10.2006, 00:55
Тормоза на загрузку хэндла в регистр, косвеную передачу управления, и недоступность регистра для передачи аргументов.

Вы в жизни не видели процессоры архитектуры 68к, вам мало 15 32-битных регистров? Это вам не х86, где каждый регистр на вес золота.

Кроме того, извольте продемонстрировать тормоза вызовов библиотек амиги, не будьте голословным!
Например так:


jsr _LVOFunctionName(a6) ; тут безусловно тормоза, целых 2 слова выбираются из памяти, по сравнению с
jsr absolute_address ; абсолютным вызовом, где один только адрес занимает 2 слова



то у Амиги "просто библиотеки". :)

yoko_ono
17.10.2006, 01:06
а про ООП в этом треде надо завязывать, imho. пока нет языка с явной поддержкой по крайней мере...



1. статическая линковка из объектников (Витамин предложил): как это сделать на спекки оптимально
Аналогично предлагаю завязывать и с этим, пока нет компилятора с явной поддержкой этого. Ни один более-менее адекватный кодер на ZX не свяжется с этой линковкой при отсутствии её поддержки в ассемблере и загрузчике. Если уж библиотека настолько незаменимая, я бы скорее потратила время на обкусывание от неё всякой линковочной шелухи или поиск сорцов, нежели чем на издевательство над собой с целью делать линкуемые при запуске программы.



2. динамическая линковка: изложить и сравнить существующие подходы (амми/libman/Win/Lin/etc.) и в результате выбрать/синтезировать то что для спека лучше подходит
Был предложен вариант динамической линковки со статически распологаемой (по указанному программой адресу) таблицей входа (JP func1:JP func2:...). Данный вариант позволяет писать программы 'как обычно', с единственной проблемой - распределением памяти под разные библиотеки. Также есть вариант libman примерно с аналогичной функциональностью, за исключением принципа вызова. Но нет же, вам подавай писизм, с обязательным исправлением абсолютных адресов везде, где только можно! Ну ничего, время лечит...

yoko_ono
17.10.2006, 01:12
Сейчас для сборки используются include. В однотекстовых ассемблерах при каждой сборке происходит елозенье по диску. В многотекстовых, когда всё в памяти, всё равно имеются тормоза с компиляцией. Если же всё лежит в памяти готовое к употреблению, нужно лишь при компиляции прилинковать один разрабатываемый модуль.

А ничего, что с любой линковкой в рунтайм будут тормоза не с компиляцией, а каждый раз - с загрузкой и линковкой? Или вы во имя идеалов писизма готовы пожертвовать чем угодно, в том числе и удобством пользователей?



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

Поверьте, никакой миграции не будет.
Вот вы лично готовы использовать вашу эту динамическую компоновку, и в каком именно программном продукте для Спектрума? Или вы готовы лишь писать десятки сообщений про 'dll-hell' и 'ооп с динамической компоновкой рулез'?

yoko_ono
17.10.2006, 01:14
Да.
Воспользоваться чужим кодом без документации невозможно.
Код для повторного использования должен быть документированым.

Раз вы так в этом уверены, то вы ни разу не проводили дизассемблирование чужих программ.




Есть два основных выхода:
1. Подсмотреть ООП на ПЦ (в TASM и т. п.).
2. Использовать typed assembly language, "типизированный ассемблер", сокращённо TAL. Идея в принципе прикручиваема к Z80. Но это - как раз сильно отдалённое будущее, о котором будем говорить гораздо позже. Ссылки здесь (http://www.wasm.ru/forum/viewtopic.php?id=8338).
Готовы ли Вы лично взяться за написание подобного ассемблера для Спектрума?

yoko_ono
17.10.2006, 01:33
И вот, я хочу написать бут, хочу написать текстовый редактор, хочу написать вьюер, хочу написать игрушку. Что из этих процедур я буду использовать? Правильно - все из них.

Скажите, а что вы будете использовать, если вы захотите написать 50fps вьювер, игрушку с выводом спрайтов через стек и кучей 256b-aligned таблиц, мультиколорную или чанковую дему, наконец? Ваш подход - опять же отдаёт писизмом, он не позволяет на СИЛЬНО ОГРАНИЧЕННЫХ ресурсах Спектрума делать действительно быстрые и крутые вещи. Если только лишь тошнить стандартными процедурами уровня инфоркома (помните, были ещё книжки - 'как написать игру на ассемблере' или 'динамическая графика') с кучей заморочек насчёт линковки, ооп и проч. пурги - то и получатся тошные программы - медленные, неинтересные.



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

За каждой из программ тянется шлейф похожих (на процедуры в других программах) процедур, и если это не те программы, от которых тошнит, а реально быстрые вещи, то каждая процедура вылизана десятки раз и адаптирована именно под конкретный случай применения. Зачем тут некие стандартные библиотеки (модули - называйте, как хотите) с 'swiss-knife type'-процедурами на все случаи жизни, с обработкой всех возможных ситуаций и тонной вариантов действий?

yoko_ono
17.10.2006, 01:44
Технология использования таких аргументов хорошо отработана. Например:

EX (SP),HL
LD A,(HL)
INC HL
LD C,(HL)
INC HL
LD B,(HL)
INC HL
EX (SP),HL Даже более привлекательно, чем ковыряться в стеке через индексные регистры.

Это технология чтения аргументов, 'вшитых' в машинный код, т.е. неизменяемых. И опять же, чтения в регистры, а не использования. Для комфортного их использования (несколько раз и в нужные моменты) их придётся переложить в память, по IX/IY ли, в абсолютную ли (по адресу). Немаловажно и то, что такие аргументы (вшитые в код) затрудняют отладку программы (не ясно, сколько таких аргументов идёт после CALL и когда они кончаются и начинается дальше код, к тому же дизассемблер воспримет их как код, выдав бессмысленные команды).

yoko_ono
17.10.2006, 01:48
Не надо нажимать RESET.
Надо выйти из вьюера. Динамический компоновщик и модули останутся в памяти.

После чего, например, запустить qc, скопировав им полностью какую-нибудь дискету на другую. Или создать рам-диск в памяти. Или запустить аласм, который всосёт в себя пару десятков исходников, разместив их в страницах, да и сам откушает страниц вдоволь.



Загрузить текстовый редактор. Он будет использовать модули уже находящиеся в памяти.

Если от них останутся следы. Иначе, он снова полезет на диск, и будет ёрзать башкой, как раненный (из скромности умолчу, куда именно).

Кстати, заодно придумайте поиск модулей по страницам и проверку их целостности, и сообщите затраты машинного времени на это.

yoko_ono
17.10.2006, 02:01
Но если полиморфизм - это силища ого-го :) , то у Амиги "просто библиотеки". :)

Кстати, уважаемый captain cobalt, раз уж вы замечены в бытности 'одептом ООП', зачитайте вот это:


Boopsi is an acronym for Basic Object Oriented Programming System for
Intuition. Using the Object Oriented Programming (OOP) model, Boopsi
represents certain Intuition entities, like Gadgets and Images, as objects.

There are many advantages to using Boopsi:

* Boopsi makes Intuition customizable and extensible. Boopsi
programmers can create new types of Boopsi objects to suit the needs
of their applications. These new types of objects are part of
Intuition and can be made public so other applications can use them.
Because applications can share the new types, application writers
don't have to waste their time duplicating each other's efforts
writing the same objects.

* New types of Boopsi objects can build on old types of Boopsi objects,
inheriting the old object's behavior. The result is that Boopsi
programmers don't have to waste their time building new objects from
scratch, they simply add to the existing object.

* OOP and Boopsi apply the concept of interchangeable parts to
Intuition programming. A Boopsi programmer can combine different
Boopsi objects (like gadgets and images) to create an entire
Graphical User Interface (GUI). The Boopsi programmer doesn't have
take the time to understand or implement the inner workings of these
objects. The Boopsi programmer only needs to know how to interact
with Boopsi objects and how to make them interact with each other.

* Boopsi objects have a consistent, command-driven interface. To the
Boopsi programmer, there is no difference between displaying a text,
border, or bitmap-based Boopsi image, even though they are rendered
quite differently. Each image object accepts a single command to
tell it to render itself.

Before reading this chapter, you should already be familiar with several
Amiga concepts. Boopsi is built on top of Intuition and uses many of its
structures. These include Intuition gadgets, images, and windows. Boopsi
also uses the tag concept to pass parameters. The "Utility Library"
chapter of this manual discusses tags. The "Utility Library" chapter also
discusses callback Hooks, which are important to the later sections of
this chapter.

OOP Overview Boopsi Gadgets
Creating a Boopsi Class Function Reference


Заметьте, и это на Амиге, на которой якобы 'просто библиотеки'. И не имеет никакого отношения к 'цэ-крест-крест', так как имеет место быть не в конструкциях языка, а на самом деле.
И на основе этой технологии написан MUI - очень замечательный и удобный оконный-графический амижный интерфейс.

captain cobalt
17.10.2006, 09:21
Уважаемый captain cobalt, скажите, вы вживую видели 'подход библиотек Амиги'? Я что-то сомневаюсь... Выше 'подход библиотек Амиги' был проклассифицирован 'в терминах винды'.

Никто из амижников не оспорил.

Вы вон давеча ажно драйвер памяти аласма записали в ООП или куда там. Признайтесь, вы даже его в глаза не видели?! Конечно же видели.

Вызов драйвера напрямую - это оптимизация, основанная на том, что в каждый момент времени существует лишь один драйвер.

Вы в жизни не видели процессоры архитектуры 68к, вам мало 15 32-битных регистров? Это вам не х86, где каждый регистр на вес золота. Больше регистров - это хорошо.
Для однопоточного программирования это очень хорошо.

Но существуют ещё языки параллельного программирования, которые, при надлежащих компиляторах, могут с пользой применять хоть миллион регистров. Впрочем, это не имеет отношения к спеку.

Кроме того, извольте продемонстрировать тормоза вызовов библиотек амиги, не будьте голословным!
Например так: Все тормоза перечислены.

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

Поверьте, никакой миграции не будет.
Вот вы лично готовы использовать вашу эту динамическую компоновку, и в каком именно программном продукте для Спектрума? Никаких новых программных продуктов сразу не будет.
Для начала предлагается адаптировать существующий софт, как то ALASM, BGE, PT. Классические игры Exolon, Earth Shaker, добавить по вкусу.

Раз вы так в этом уверены, то вы ни разу не проводили дизассемблирование чужих программ. Проводили.

И даже можно провести параллель.

Разбирая одну программу, в принципе, всё что нужно, можно держать в человеческой памяти. Но если параллельно разбирать десять программ, придётся записывать на бумажку.

Точно так же и с библиотеками.
Одну библиотеку ещё можно использовать без документации. Десяток библиотек - никто не будет.


Есть два основных выхода:
1. ...
2. ...
Готовы ли Вы лично взяться за написание подобного ассемблера для Спектрума? Подобный ассемблер уже пишется несколько месяцев. Вялотекущими темпами, как и всё на спеке. Здесь были изложены отдельные идеи из проектной документации. Когда (если) он выйдет, обнаружится что все знают как им пользоваться. :)

Но. Сначала компиляция в динамически компонуемые модули, и только потом (необязательно) то что процитировано.

Скажите, а что вы будете использовать, если вы захотите написать 50fps вьювер, игрушку с выводом спрайтов через стек и кучей 256b-aligned таблиц, мультиколорную или чанковую дему, наконец? В некоторой степени это возможно.
Это всё примеры на динамическую кодогенерацию.

Можно дать модулю побольше памяти - и пусть он в неё разворачивает процедуры и вызывает их.

Здесь начинается гибкость против скорости. Гибкость может быть очень полезной штукой на практике. Скорость же в стиле "демо на посмотреть один раз" может имет гораздо меньшее значение. Ибо "пиксели Спектрума никого не плющат".

Это технология чтения аргументов, 'вшитых' в машинный код, т.е. неизменяемых. И опять же, чтения в регистры, а не использования. Для комфортного их использования (несколько раз и в нужные моменты) их придётся переложить в память, по IX/IY ли, в абсолютную ли (по адресу). Немаловажно и то, что такие аргументы (вшитые в код) затрудняют отладку программы (не ясно, сколько таких аргументов идёт после CALL и когда они кончаются и начинается дальше код, к тому же дизассемблер воспримет их как код, выдав бессмысленные команды). Всё правильно.
Речь только про то, чтобы предусмотреть для них синтаксис для объявления в сигнатуре.

После чего, например, запустить qc, скопировав им полностью какую-нибудь дискету на другую. Или создать рам-диск в памяти. Или запустить аласм, который всосёт в себя пару десятков исходников, разместив их в страницах, да и сам откушает страниц вдоволь. Ну и в чём проблема.
Ненужные библиотеки можно выкинуть из памяти.
Если совсем припёрло, можно и динамический компоновщик выкинуть.
Получится точно такой же qc\alasm, но перезагружаться опять через RESET.

Если от них останутся следы. Иначе, он снова полезет на диск, и будет ёрзать башкой, как раненный (из скромности умолчу, куда именно).

Кстати, заодно придумайте поиск модулей по страницам и проверку их целостности, и сообщите затраты машинного времени на это. Не предусмотрено такого механизма.

Есть модули - программа работает. Убиты модули - программа не работает; RESET; загрузка модулей с диска.

Кстати, уважаемый captain cobalt, раз уж вы замечены в бытности 'одептом ООП', зачитайте вот это: Хорошо.
Я не против.

А как насчёт ООП на спеке? ;)

Vitamin
17.10.2006, 09:35
Имеется ввиду, нужен синтаксис для сигнатуры.
Нужен- сделаем. Ничего не теряем, в общем случае.


Код с сигнатурой в комментарии можно компилировать прямо сейчас, в любом ассемблере (после токенизации). То есть сию секунду можно нарабатывать код. Параллельно можно разрабатывать спец компилятор и документатор.
Что есть токенизация? Дополнительный проход некой утилитой? А ее нету. И пересадить программистов под новый, пока не существующий компилятор менее реально, чем пересадить всех под существующий аласм.
Тем более, макросы можно портировать под любой более-менее серьезный ассемблер. А для прочих "игрушечных" уж ничего не получится...


Надо выйти из вьюера. Динамический компоновщик и модули останутся в памяти.
Загрузить текстовый редактор. Он будет использовать модули уже находящиеся в памяти.
Смотри на вещи шире. Предполагаемый подход твоей хотелки не отрицает. Поясню. Предположим, есть некий суровый модуль SYSTEM, который содержит функции Exit и LoadLibrary. В простейшем случае первая функция будет выходом в дос, а вторая- просто загрузкой файла. Подменяем этот модуль на свой и _автоматически_ получаем возможность выхода в некую оболочку (от RC до ОС) и загрузку модулей с кешированием.


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


какие уже (в настоящее время) есть вещи так или иначе связанные с модульной организацией (полный список, включая документацию). Что нужно чтобы сие стало "скорее живым, нежели мёртвым"?
Первая стабильная версия библиотеки: http://zxdocs.fatal.ru/coding/module.zip Уже не хватает возможностей, планирую расширять.


Уважаемый captain cobalt, скажите, вы вживую видели 'подход библиотек Амиги'? Я что-то сомневаюсь... Вы вон давеча ажно драйвер памяти аласма записали в ООП или куда там. Признайтесь, вы даже его в глаза не видели?!
Я, конечно, дико извиняюсь, товарищ, но на все высказанные просьбы рассказать, в чем же есть круть несусветная амиги были получены однообразные ответы типа "смотрите libman, там все". Ну посмотрели, сделали выводы на основе неполной (уж сколько было) информации.

Vitamin
17.10.2006, 09:42
Если уж библиотека настолько незаменимая, я бы скорее потратила время на обкусывание от неё всякой линковочной шелухи или поиск сорцов, нежели чем на издевательство над собой с целью делать линкуемые при запуске программы.
Что есть линковочная шелуха? В итоге должен вместо универсального модуля получиться сухой кодовый блок, жестоко скомпилированный под определенный адрес? Да... Универсальность так и прет.

ЗЫ. Я человек дикий, честно говорю, что не знаю всех возможностей аласма. Просвятите меня дремучего, как же так сделать чтоб невызываемые функции не компилировались?

captain cobalt
17.10.2006, 09:44
Фишка в том, что уже "вставленные" в программу модули не получится отделить от программы - это такое свойство модульной структуры. Модули не "вставляются" в программу.
Программа загружается поверх библиотечных модулей.
Когда программа завершается, модули остаются и не трогаются.
Теперь поверх них можно загрузить другую программу.

Заменим слово "модули" на слово "ОС".
ОС "вставляется" в программу? Нет.
ОС можно отделить от программы? Можно.
Тогда зачем нужно "свойство модульной структуры"?

Чтобы чего-нибудь там расширить придётся грузить ассемблер (или ЯВУ если угодно) править программу и включать в неё указание на эти модули. Технология динамической подгрузки здесь не канает, потому что уже запущенное приложение не должно нуждаться ни в одной библиотеке и работать самостоятельно. Это опять "дух процедурного программирования". :)

Функциональностью не обязательно пользоваться явно.

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

captain cobalt
17.10.2006, 10:02
Что есть токенизация? Перевод из plain text в "формат ассемблера".

Ни один из широко используемых спековых ассемблеров не использует plain text для исходников.

Дополнительный проход некой утилитой? А ее нету. Такая утилита есть.
Для каждого ассемблера своя.

Смотри на вещи шире. Предполагаемый подход твоей хотелки не отрицает. Вижу, что не отрицает.

Как??? Как программа на этапе выполнения может расширить свой функционал за счет дополнительных модулей, если она про них ни сном ни духом??? Это опять "дух процедурного программирования". :)

Рассмотрим на примере Linux. :)
У него есть загружаемые модули ядра.
Загрузим такой модуль. Смонтируем.
Всё. Теперь любая программа может пользовать функциональность модуля через стандартный файловый ввод-вывод, хотя о самом модуле "ни сном ни духом".

Теперь обобщим на произвольный программный интерфейс (не только файловый).
Понятно?

Vitamin
17.10.2006, 10:34
Перевод из plain text в "формат ассемблера".
Ни один из широко используемых спековых ассемблеров не использует plain text для исходников.
Зато как минимум один ассемблер использует существующие наработки. Лучше синица в руке, чем утка под кроватью %)


Такая утилита есть.
Для каждого ассемблера своя.
Уж тогда возложить на эту утилиту генерацию таблиц для создания релоцируемого кода. Иначе никак.


Это опять "дух процедурного программирования".

Рассмотрим на примере Linux.
У него есть загружаемые модули ядра.
Загрузим такой модуль. Смонтируем.
Всё. Теперь любая программа может пользовать функциональность модуля через стандартный файловый ввод-вывод, хотя о самом модуле "ни сном ни духом".
Теперь обобщим на произвольный программный интерфейс (не только файловый).
Понятно?
Ну вот... Попался... Я если честно, чтото не припомню полиморфизма в ядре линукса. Для того чтобы удостовериться, даже спросил у человека, который разрабатывал эти модули- нету там неявного вызова!!! Нечто похожее есть только при регистрации файлового интерфейса спецустройств, да и то, ядро о твоем модулей и знать не знает пока ты явно не постучишься к обслуживаемому им устройству. Я уже не говорю про простые модули, которые в ядре просто висят и обращение к ним идет по конкретным именам функций, которые должны быть уникальны во всем адресном пространстве!

captain cobalt
17.10.2006, 11:10
"Монтирование" с точки зрения ядра Linux это что?

Vitamin
17.10.2006, 11:16
"Монтирование" с точки зрения ядра Linux это что?
Вызов функций специфичного модуля, название которого указывается при выполнении операции. И вообще, монтирование тут не при чем по большому счету.

Давай вернемся к простому примеру- та абстрактная библиотека GUI, поддерживающая расширение за счет единого интерфейса разных виджетов. Ты можешь прилинковать кучу модулей со своими виджетами, но библиотека их не будет использовать, потому что ничего не знает про них. Про них должен знать клиент этой библиотеки, который создает объекты, интерфейс которых реализован в тех модулях. Т.е. он должен знать о них. А если программа не знает, она не будет их использовать. Иными словами, расширение функционала программ за счет загрузки дополнительных модулей невозможна, если не предусмотрены специальные возможности для этого (типа загрузка длл и проч).

captain cobalt
17.10.2006, 11:21
Уж тогда возложить на эту утилиту генерацию таблиц для создания релоцируемого кода. Это тоже идея.

Отдельно компилировать любым ассемблером в "плоский код".

Отдельно утилитой - собирать "символьный файл".

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

При таком способе сигнатура прописывается в комментарии. ;)

elf/2
17.10.2006, 11:25
Я тут наброски делал по поводу организации сигнатуры. Часть подсмотрел, часть придумал сам. Вот что получилось.




проверка сигнатур нормально работает только на этапе компиляции.

Чего???? Как раз только на этапе линковки. Чтобы знать что и с чем склеивать.
ребятушки это уже не смешно... мангленые имена функций с сигнатуруй появились в компиляторах C++ как workaround: необходимо было как-то разрешать перегруженные функции, а формат obj файлов не содержал типов аргументов. пришлось делать уникальные имена для перегруженных функций. соответсвенно в момент компиляции когда компилятор знает типы всех аргументов при вызове функции он создает это хитрое имя а линкер просто сравнивает две строчки... вы хотите делать перегруженные функции на асме? это не возможно, поскольку синтаксис ассемблера не содержит комманды вызова функции с агрументами.

В клиентском коде используется только memcpy. VI#43543 просто копируется в клиентский модуль с объектным кодом во время компиляции. Во время динамической компоновки они просто проверяются на равенство.
вот именно, попробуйте написать функцию которая имея в регистре A номер экранной линии возвращает адрес в HL и ее вызов в терминах вашего мифического компилятора. и объясните кто и как будет формировать мангленое имя _при вызове_

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


ну и главное: всемогуторы не летают!

elf/2
17.10.2006, 11:32
Но нет же, вам подавай писизм, с обязательным исправлением абсолютных адресов везде, где только можно! Ну ничего, время лечит...
ну сколько можно, Лена... я уже два раза написал, что на Windows/Linux при загрузке никто абсолютных адресов не правит. делается именно то, что вы предлагали. изменяются адреса только в таблице jump'ов. единственное отличие в том что это делает система а не библиотека.


Аналогично предлагаю завязывать и с этим, пока нет компилятора с явной поддержкой этого. Ни один более-менее адекватный кодер на ZX не свяжется с этой линковкой при отсутствии её поддержки в ассемблере и загрузчике.
с тем что Витамин и captain cobalt "увлеклись" и пытаются придумать очередной всемогутор, который во-первых сделать не реально, а во-вторых никто использовать не будет согласен

Vitamin
17.10.2006, 11:33
elf/2: ты прав насчет проблем и всего-всего. Но есть одна маленькая хитрость. По крайней мере у меня. Все дело в том, что символическое имя и внутреннее имя в исходнике могут различаться!!! И все прекрасно ложится тогда!
Например, импортируем две перегруженные функции с разной сигнатурой.

__EXTERN "onefunc@B(DD)",func_ver_1
__EXTERN "onefunc@B(WW)",func_ver_2
...
;гдето в коде
CALL_ func_ver_1 ;зовем первую функцию
...
CALL_ func_ver_2 ;зовем вторую функцию

равнозначно экспортирование
__PUBLIC "myfunc@W(BB)",FUNCTION
myfunc1
....

__PUBLIC "myfunc@W(WW)",FUNCTION
myfunc2
...

Вот и все! И нет никакого конфликта!


Это тоже идея.
Отдельно компилировать любым ассемблером в "плоский код".
Отдельно утилитой - собирать "символьный файл".
Динамический компоновщик будет брать для каждого модуля эти два файла. Когда компоновка завершена, таблицы символов можно выбросить из памяти.
При таком способе сигнатура прописывается в комментарии.
Не совсем. Утилита берет исходник, генерит на базе него другой исходник, в котором внутри прописаны все таблицы релокации, вся сигнатура функций и прочая, а вот этот второй исходник уже используется для компиляции в обычный объектный код, списываемый на диск в виде модуля.
И таблицы символов из файла выкидывать нельзя. Нужно оставить хотя бы хеши сигнатур, иначе ничего не получится.

Vitamin
17.10.2006, 11:37
с тем что Витамин и captain cobalt "увлеклись" и пытаются придумать очередной всемогутор, который во-первых сделать не реально, а во-вторых никто использовать не будет согласен
Я уже давно все придумал и написал. Теперь вот пытаюсь с помощью присутствующих улучшить и применить несколько шире, чем только в моих проектах. А то за%%%ло что на каждую идею начинаются крики "да это уже есть на платформе ..., нефиг выдумывать, и вообще ты писюканец". И сидят такие пальцы гнутые, сами нихера не сделали...
Не спорю, сам такой иногда бываю, но хоть пытаюсь с грехом пополам разобраться в предложении и идеях.

elf/2
17.10.2006, 11:39
Предполагается, что автор memcpy изменив интерфейс (или внеся иную несовместимость) изменит сигнатуру. Несовместимые модули не будут компоноваться. Если автор забудет изменить сигнатуру, то вспомнит когда у него что-нибудь сломается. Если у него ничего не сломается, ему сообщит кто-нибудь, у кого сломается. Если автор забил на спек, проблема может быть опубликована.
если у библиотеки/библиотечной функции изменяется интерфейс, то у библиотеки меняется номер версии и линкер на основании требовании программы к ВЕРСИИ библиотеки с новой версией линковать не будет.

elf/2
17.10.2006, 11:43
__EXTERN "onefunc@B(DD)",func_ver_1
__EXTERN "onefunc@B(WW)",func_ver_2
...
;гдето в коде
CALL_ func_ver_1 ;зовем первую функцию
...
CALL_ func_ver_2 ;зовем вторую функцию

причем здесь перегрузка? ты руками назначаешь алиас для фукнкии и по нему ее вызываешь.

при настоящей перегрузке, ассемблер должен "магическим" образом проанализировать твой код перед CALL_ и понять какой из вариантов onefunc ты имел в виду и вызвать его

captain cobalt
17.10.2006, 11:46
Давай вернемся к простому примеру- та абстрактная библиотека GUI, поддерживающая расширение за счет единого интерфейса разных виджетов. Пусть имеется функция "нарисовать окно с виджетами". Ей аргументом передаётся множество всех виджетов, она пробегается по нему и для каждого виджета вызывает виртуальную функцию "нарисовать".

Пусть имеется программа которая использует эту функцию.

Программа порисовала виджеты.

Теперь мы вышли из программы, и запустили другую программу, которая использует новые виджеты. Модули с этими виджетами загрузились при запуске программы. Программа передаёт этой функции новые виджеты, и, о чудо, функция "научилась" рисовать только что загруженные виджеты. :)

elf/2
17.10.2006, 11:46
Я уже давно все придумал и написал. Теперь вот пытаюсь с помощью присутствующих улучшить и применить несколько шире, чем только в моих проектах.
тогда надо было начинать с рассказа о том что уже есть и как это работает. и обязательно объяснить чем это лучше/удобнее других методов.

icebear
17.10.2006, 11:53
Сигнатура - это часть документации.

Т.е. CLSID - это часть доки по винапи?


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

Ты писал на С? На разных компиляторах? Если писал, то знаешь, что разные компиляторы по-разному ведут себе с неиницализироваными переменными. Ничем не отличается от твоего примера. К чему я это сказал? К тому, что с этой проблемой не стоит заморачиваться.

Vitamin
17.10.2006, 11:55
Пусть имеется функция "нарисовать окно с виджетами". Ей аргументом передаётся множество всех виджетов, она пробегается по нему и для каждого виджета вызывает виртуальную функцию "нарисовать".

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


Теперь мы вышли из программы, и запустили другую программу, которая использует новые виджеты. Модули с этими виджетами загрузились при запуске программы. Программа передаёт этой функции новые виджеты, и, о чудо, функция "научилась" рисовать только что загруженные виджеты.
Все так, но ты сам себе противоречишь. Невозможно добавлять новые виджеты (сиречь расширять функционал) уже готовой программы! Она использует только те понятия (библиотеки), о которых знает на момент компиляции. Так что расширение функционала готовых программ прямо так в лоб невозможно.


тогда надо было начинать с рассказа о том что уже есть и как это работает. и обязательно объяснить чем это лучше/удобнее других методов.
Ссылка на документацию есть. Рассказывал я про нее неоднократно в разных местах. Библиотека в течение трех лет уже разрабатывается, так что кое-какие наработки есть и мне очень и очень понравились получаемые возможности- один и тот же контейнер для хранения кода может служить и готовым приложением (для некой ОС) и статической библиотекой и динамической библиотекой. Для любителей керналя можно реализовать и его без каких бы то ни было проблем! Вот скажите, спецы по амиге, можно ли (если да, то как) экспортировать из модуля данные? Функции экспортируются через керналь по индексу, а вот если мне надо, например, использовать шрифт или текст, зашитый в библиотеке, я смогу это сделать без использования специальных методов получения адреса?

captain cobalt
17.10.2006, 12:05
ребятушки это уже не смешно... мангленые имена функций с сигнатуруй появились в компиляторах C++ как workaround: необходимо было как-то разрешать перегруженные функции, а формат obj файлов не содержал типов аргументов. пришлось делать уникальные имена для перегруженных функций. соответсвенно в момент компиляции когда компилятор знает типы всех аргументов при вызове функции он создает это хитрое имя а линкер просто сравнивает две строчки... Это правильно.

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

вот именно, попробуйте написать функцию которая имея в регистре A номер экранной линии возвращает адрес в HL и ее вызов в терминах вашего мифического компилятора. и объясните кто и как будет формировать мангленое имя _при вызове_ Пусть есть уже написанная функция. У неё есть вручную прописанная сигнатура. При компиляции хэш сигнатуры попадает в таблицу экспорта.

Теперь мы хотим воспользоваться этой функцией из другого модуля. Делаем мы это только по имени. При компиляции хэш сигнатуры из упомянутой таблицы экспорта просто копируется в таблицу импорта этого нового модуля. Чтобы компоновщик проверял на равенство. Вот и всё.

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

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

если у библиотеки/библиотечной функции изменяется интерфейс, то у библиотеки меняется номер версии и линкер на основании требовании программы к ВЕРСИИ библиотеки с новой версией линковать не будет. Версия это слишком грубо.
Линуксоиды это знают. Когда есть совместимая библиотека, но другой версии, с которой новый софт не собирается.

Сигнатура - это проверка именно по совместимости, а не по версии.

Причём каждого символа отдельно. Если та часть модуля, которая используется - совместима, то модуль компонуется.

elf/2
17.10.2006, 12:06
Ссылка на документацию есть. Рассказывал я про нее неоднократно в разных местах.
документация это modules.txt внутри modules.zip? такой подход не прокатит :(

нужны примеры: зачем это, чем это лучше... ну и как минимум группа товарищей которая это использует. а большинство посетителей форума (включая меня) это теоретики :(

Vitamin
17.10.2006, 12:11
Это тоже правильно.
Я не хочу перегруженные функции на ассемблере.
"-Святой отец! Моя жена жуткая стерва, она меня постоянно оскорбляет!
-Разводитесь
-Но я ее люблю!
-Не разводитесь"
Это я к тому что есть возможность реализовать перегруженые функции (для этого никаких усилий даже не потребуется), а вот использовать или нет их- это уже личное дело программиста.


Это уже компилятор.
Зачем из исходника в исходник, если можно прямо в объектный файл?
Да? А таблицы релокации ты как будешь делать? Если ассемблер не поддерживает макросов, то необходимо будет создание дополнительных промежуточных таблиц с адресами адресозависимых точек.


Их можно положить в отдельный файл. Это неважно.
Всё равно без них компоновщик ничего не будет компоновать.
Зачем множить сущности? Разбивка на два файла имеет смысл разве что для отладки...
Эт я так, к сведению, не споря %)

Vitamin
17.10.2006, 12:12
документация это modules.txt внутри modules.zip? такой подход не прокатит

нужны примеры: зачем это, чем это лучше... ну и как минимум группа товарищей которая это использует. а большинство посетителей форума (включая меня) это теоретики
А какой подход покатит? А то просили "хоть чтото". Дал все что есть- "не прокатит"...
Могу подкинуть ряд готовых модулей, простенький настройщик и исходник линкера (неоптимальный).

acidrain
17.10.2006, 12:14
ЗЫ. Доки получил?
Да, сенкс. Вот подумал будет не лишним, ведь АОС развивается и теперь есть бета-АОС 4 для ППЦ процов. Некоторая инфа, касательно либ и не только http://www.totalamiga.org/pdf/totalamiga_19.pdf
остальные номера, но не все можно почитать тут: http://www.totalamiga.org/backissues2.html

elf/2
17.10.2006, 12:32
Пусть есть уже написанная функция. У неё есть вручную прописанная сигнатура. При компиляции хэш сигнатуры попадает в таблицу экспорта.

Теперь мы хотим воспользоваться этой функцией из другого модуля. Делаем мы это только по имени. При компиляции хэш сигнатуры из упомянутой таблицы экспорта просто копируется в таблицу импорта этого нового модуля. Чтобы компоновщик проверял на равенство. Вот и всё.
с этого момента поподробнее:
1. у нас есть библиотека xyz.lib
2. у нее в таблице экспорта есть функция get_scr_addr@r_v_q

3. пишем программу которая эту функцию должна звать:
----------
require 'xyz.lib'

ld a, 5
call xyz.get_scr_addr
----------
если мифический компилятор просто будет искать в таблице экспорта библиотеки функцию начинающуюся с get_scr_addr@ и прописывать ее полное имя в таблице импорта программы то это ничего не дает кроме тех случаев когда мы сильно поменяли интерфейс данной конкретной функции. а интерфейс - это святое! если мы начинаем его постояноо менять то это уже нельзя назвать библиотекой.

причем если мы добавили в новую версию библиотеки функцию инициализации которая ДОЛЖНА вызываться первой, и пользователь об этом не знал/забыл то все эти сигнатуры не помогут. и линкер без ошибок все слинкует

Версия это слишком грубо.
Линуксоиды это знают. Когда есть совместимая библиотека, но другой версии, с которой новый софт не собирается
однако и на винде (activex, .net) и на линуксе используются именно версии библиотеки. обычно есть minor и major версии. и софт не будет собираться если поменялась major версия, но смена мажорной версии как-раз и говорит о том что совместимости нет. если поменялась минорная версия, то как правило все собирается

elf/2
17.10.2006, 12:36
А какой подход покатит? А то просили "хоть чтото". Дал все что есть- "не прокатит"...
честно? боюсь что никакой. при наличии одного-двух активных разработчиков на платформе...

но если будет getting started guide с простыми примерами и объяснением как данный подход позволяет экономить время/ресурсы, то есть маленькая надежда что кто-нибудь и попробует

Vitamin
17.10.2006, 12:41
честно? боюсь что никакой. при наличии одного-двух активных разработчиков на платформе...
Значит в Бобруйск тогда. Буду делать как мне удобно и применять чисто в своих проектах. Прощай, мечта...

captain cobalt
17.10.2006, 12:43
Т.е. CLSID - это часть доки по винапи? Это "закулисный механизм", который из клиентского кода не виден.
Сигнатура так и работает.

Ты писал на С? На разных компиляторах? Если писал, то знаешь, что разные компиляторы по-разному ведут себе с неиницализироваными переменными. Ничем не отличается от твоего примера. К чему я это сказал? К тому, что с этой проблемой не стоит заморачиваться. На Ц можно поставить "хороший стиль".
А в ассемблере до сих пор иногда случается проблема.

Все так, но ты сам себе противоречишь. Невозможно добавлять новые виджеты (сиречь расширять функционал) уже готовой программы! Она использует только те понятия (библиотеки), о которых знает на момент компиляции. Так что расширение функционала готовых программ прямо так в лоб невозможно. Модули, расширяющие функционал - это плагины.

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

Чтобы плагины можно было добавлять во время работы, нужно чтобы в этот список можно было добавлять элементы.

Где может располагаться этот список? Есть два основных способа:

1. В программе. Программа сама делает LoadLibrary и сама добавляет элемент себе в список.

2. В общеизвестном месте. Пользователь составляет нужный список и размещает в этом месте. Общеизвестное место загружает эти модули при запуске программы. Программа использует уже готовый список и не напрягается на LoadLibrary.

Что это за общеизвестное место? Это просто модуль. Точнее, список плагинов хранится не в модуле, а на диске. То есть сохраняется между выключениями машины. А модуль это просто интерфейс к этому дисковому хранилищу.

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

И название этому дисковому хранилищу - реестр. :)

icebear
17.10.2006, 12:48
Это "закулисный механизм", который из клиентского кода не виден.
Сигнатура так и работает.

Как это "закулисный"? Доступ к COM именно по CLSID происходит. Т.е. это и есть сигнатура.


На Ц можно поставить "хороший стиль".
А в ассемблере до сих пор иногда случается проблема.

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

captain cobalt
17.10.2006, 13:04
с этого момента поподробнее:
1. у нас есть библиотека xyz.lib
2. у нее в таблице экспорта есть функция get_scr_addr@r_v_q

3. пишем программу которая эту функцию должна звать:
----------
require 'xyz.lib'

ld a, 5
call xyz.get_scr_addr
----------
если мифический компилятор просто будет искать в таблице экспорта библиотеки функцию начинающуюся с get_scr_addr@ и прописывать ее полное имя в таблице импорта программы то это ничего не дает кроме тех случаев когда мы сильно поменяли интерфейс данной конкретной функции. а интерфейс - это святое! если мы начинаем его постояноо менять то это уже нельзя назвать библиотекой. Всё правильно.

На спеке "весь код уже написан".
На продолжающих развитие платформах есть такие штуки как obsolete и deprecated.

причем если мы добавили в новую версию библиотеки функцию инициализации которая ДОЛЖНА вызываться первой, и пользователь об этом не знал/забыл то все эти сигнатуры не помогут. и линкер без ошибок все слинкует Инициализация - это важно.
Функцию инициализации модуля должен вызывать линкер.

однако и на винде (activex, .net) и на линуксе используются именно версии библиотеки. обычно есть minor и major версии. и софт не будет собираться если поменялась major версия, но смена мажорной версии как-раз и говорит о том что совместимости нет. если поменялась минорная версия, то как правило все собирается 1. Если совместимость осталась, то линкеру не должно быть дела до minor номера?

2. Что если в данной версии совместимость нарушилась, а в следующей опять восстановилась?

3. Что если часть модуля осталась совместимой, а часть нет? Сигнатура для каждого символа модуля разруливает именно это.

captain cobalt
17.10.2006, 13:11
Как это "закулисный"? Доступ к COM именно по CLSID происходит. Т.е. это и есть сигнатура. Хорошо.
Осталось только выяснить связь между COM и WinAPI. :)

elf/2
17.10.2006, 13:40
1. Если совместимость осталась, то линкеру не должно быть дела до minor номера?
2. Что если в данной версии совместимость нарушилась, а в следующей опять восстановилась?
3. Что если часть модуля осталась совместимой, а часть нет? Сигнатура для каждого символа модуля разруливает именно это.
1. чаще всего да, но если очень надо то можно указывать зависимость с точностью до минорной версии. например при минорном update могла добавиться новая функци, это совместимости не вредит (при правильном использовании конечно)
2. значит не судьба :) или указывать указывать список возможных версий при импорте
3. значит это новая версия и звать функции с неизменившимися сигнатурами скорее всего опасно. т.к. они могут иметь side effects


Инициализация - это важно. Функцию инициализации модуля должен вызывать линкер.
инициализацию модуля я привел в качестве примера, что делать если сигнатура функции (т.е. распределение аргументов по регистрам) не поменялась, но поменялись значения кодов возврата, т.е. раньше 0 означал успех, а в новой версии - ошибку. линкер это проглотит, но программа работать не будет... можно придумать и другие варианты.


Где может располагаться этот список? Есть два основных способа:
1. В программе. Программа сама делает LoadLibrary и сама добавляет элемент себе в список.
зачем список? почему не искать все файлы удовлетворяющие маске и лежащие в определенном месте (каталоге?)

maximk
17.10.2006, 13:53
У меня по этому поводу одна идея- проводить вырезание только нужных функций. Но это требует ресурсов и может быть применено только при окончательной сборке бинарника (не runtime).
А про CP/M (точнее, реализацию) поподробнее можно?
Такое я видел в Pascal MT+, т.е. в его библиотеках. При линковке проги со стадартной библиотекой PASLIB.ERL от туда дергались только нужные функции. Как оно там внутри работало - не знаю. Это же закрытые коммерческие продукты. Кроме того, формат ERL - это, по словам разработчиков MT+, улучшенный формат REL, который являлся де-факто стандартом для перемещаемых объектных модулей под CP/M. REL могли генерить некоторые ассемблеры и компиляторы.

Сам формат REL кажется даже документирован, т.е. где-то описание я встречал, но где - не помню. Скорее всего в документации к dev-средствам от Digital Research.

Vitamin
17.10.2006, 14:22
зачем список? почему не искать все файлы удовлетворяющие маске и лежащие в определенном месте (каталоге?)
Ага. А там лежат несколько версий одной и той же библиотеки и линкер впадает в ступор перед проблемой выбора. Да память не резиновая вроде как...


Сам формат REL кажется даже документирован, т.е. где-то описание я встречал, но где - не помню. Скорее всего в документации к dev-средствам от Digital Research.
Спасибо, буду искать

captain cobalt
17.10.2006, 14:38
1. чаще всего да, но если очень надо то можно указывать зависимость с точностью до минорной версии. например при минорном update могла добавиться новая функци, это совместимости не вредит (при правильном использовании конечно)
2. значит не судьба :) или указывать указывать список возможных версий при импорте
3. значит это новая версия и звать функции с неизменившимися сигнатурами скорее всего опасно. т.к. они могут иметь side effects

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

Ну что тут сказать?

У каждого подхода есть недостатки.

С одной стороны, если целостность не контролируется - получается DLL hell. Если есть контроль версий - получаем несовместимость потенциально совместимого кода.

Контроль по сигнатурам - это некоторое промежуточное решение. И наследует достоинства и недостатки обоих подходов. Если это иметь ввиду, то подход весьма практичен. ;)

зачем список? почему не искать все файлы удовлетворяющие маске и лежащие в определенном месте (каталоге?) Самое главное в списке - то что из него можно так или иначе получить указатели на функции плагинов и вызывать их.

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

Ещё можно вообразить пользователя с одним дисководом. У него есть дискета с графическим редактором и плагинами. Он запускает редактор и автоматически загружаются плагины которые он настроил. Но все плагины не помещаются на дискету, и иногда он загружает плагины, которые хранятся на другой дискете. А ещё у него есть дискеты с его картинками. Не получится просто искать файлы в каталоге по маске. :)

caro
17.10.2006, 14:51
... буду искатьА чего искать, читай, думаю будет полезно.

elf/2
17.10.2006, 14:53
С одной стороны, если целостность не контролируется - получается DLL hell. Если есть контроль версий - получаем несовместимость потенциально совместимого кода.

блин, dll hell к целосности отношение имеет слабое. проблема в том что в свое время MS рекомендовала складывать все dll в папочку %windir%\system. при установке двух программ использующих одну библиотеку разных версий побеждала последняя. инсталятор мог проверить только дату/время изменения файла.
для борьбы с этим добавили version_info, чтобы опять же инсталятор мог грамотно сообщить пользователю что происходит и положить библиотеку в папку к программе откуда она будет грузиться в первую очередь

для того чтобы hell'а не было достаточно иметь возможность хранить несколько версий библиотеки на одной машине. это работает в linux и .net


Ага. А там лежат несколько версий одной и той же библиотеки и линкер впадает в ступор перед проблемой выбора. Да память не резиновая вроде как...

а вы так не делайте :) кстати наличие реестра с общим списком всех библиотек в системе от всего этого не спасает



Ещё можно вообразить пользователя с одним дисководом. У него есть дискета с графическим редактором и плагинами. Он запускает редактор и автоматически загружаются плагины которые он настроил. Но все плагины не помещаются на дискету, и иногда он загружает плагины, которые хранятся на другой дискете. А ещё у него есть дискеты с его картинками. Не получится просто искать файлы в каталоге по маске.

точно, но вот только где в таком случае будет лежать "реестр"? и как он поможет разрешить проблему

elf/2
17.10.2006, 15:04
А чего искать, читай, думаю будет полезно.
тогда просто ради коллекции ссылка на описание формата obj файлов от MS OMF (relocatable object module format):
http://www2.cs.uh.edu/~mirkovic/cosc2410/omf1_1.pdf

captain cobalt
17.10.2006, 15:20
есть возможность реализовать перегруженые функции (для этого никаких усилий даже не потребуется), а вот использовать или нет их- это уже личное дело программиста. Чтобы использовать перегруженные функции, нужно руками прописывать сигнатуры в клиентском коде.

Да? А таблицы релокации ты как будешь делать? Если ассемблер не поддерживает макросов, то необходимо будет создание дополнительных промежуточных таблиц с адресами адресозависимых точек. Утилита, делающая из исходников исходники - это компилятор. Лучше сразу обучить её делать объектные файлы. Тогда "старые ассемблеры" можно отбросить. :)

для того чтобы hell'а не было достаточно иметь возможность хранить несколько версий библиотеки на одной машине. это работает в linux и .net Можно ли на спеке позволить себе держать разные версии библиотеки в памяти? Скорее всего нет.

Поэтому и важно, что если совместимость достаточна - библиотека компонуется. Недостаточна - проблема должна обнаруживаться.

Каждая библиотека должна быть одна.

точно, но вот только где в таком случае будет лежать "реестр"? и как он поможет разрешить проблему Пока не ясно.
Он может лежать на "системном диске", и после загрузки постоянно сидеть в памяти.
Или же каждый кусок может лежать рядом со своей программой в "файле конфигурации".

для того чтобы hell'а не было достаточно иметь возможность хранить несколько версий библиотеки на одной машине. это работает в linux и .net Есть ещё один способ хранить несколько версий библиотек на одной машине.

Компоновать программы статически. :)

тогда просто ради коллекции ссылка тоже подкину пару ссылок:

Vitamin
17.10.2006, 15:33
а вы так не делайте кстати наличие реестра с общим списком всех библиотек в системе от всего этого не спасает
Вполне можно так делать. Коренным образом поменялась библиотека- меняется имя/версия и она не прилинкуется "куда не надо". А реестр- это бред.


Чтобы использовать перегруженные функции, нужно руками прописывать сигнатуры в клиентском коде.
А чтобы использовать ассемблер надо вообще программы писать ручками! Прикинь, да?


Утилита, делающая из исходников исходники - это компилятор. Лучше сразу обучить её делать объектные файлы. Тогда "старые ассемблеры" можно отбросить.
Ну-ну. Никто не выказывал охоты перейти на существующий аласм, зато как только на горизонте нарисуется эфемерный компилятор, так все сразу побегут роняя тапки пользовать его и писать в нем програмы. Уж лучше использовать что есть.

elf/2
17.10.2006, 15:34
Можно ли на спеке позволить себе держать разные версии библиотеки в памяти?
не в памяти, а на диске. соответсвенно когда задаем зависимости от библиотек указываем не только имя но и версию. и компоновщик грузит в память только нужную версию


Он может лежать на "системном диске", и после загрузки постоянно сидеть в памяти.
"Можно ли на спеке позволить себе держать ... в памяти?" :) нужное вставить


Или же каждый кусок может лежать рядом со своей программой в "файле конфигурации".
точно, и добавить в каждую программу парсер конфигурашек... "Можно ли на спеке позволить себе держать ... в памяти?"

elf/2
17.10.2006, 15:45
Коренным образом поменялась библиотека- меняется имя/версия и она не прилинкуется "куда не надо".

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

и линковка должна проходить/отваливаться на основе требований программы к версии библиотеки.

при этом не важно как мы эти библиотеки находим. насколько мне известно подход к поиску библиотек у винды/линукса различается, но:
1. можно указать руками где искать при запуске (LD_LIBRARY_PATH)
2. место специфичное для данной программы (каталог где лежит бинарик)
3. общая куча (%windir%\system)


А реестр- это бред.
как сейчас модно писать: +1

Vitamin
17.10.2006, 15:47
"Можно ли на спеке позволить себе держать ... в памяти?" нужное вставить
Я тоже было подумал, что черная кошка пробежала дважды, но ты меня опередил %)

Единственное что полезное вытащил из идей captain cobalt'а- это версионирование на уровне функций, а не модулей целиком. Но это только если будет возможность раздербанивать библиотеки, вытаскивая нужные функции. В противном случае это не имеет смысла.

Vitamin
17.10.2006, 15:49
вот и я о том. у библиотеки должна быть версия, а не у функции сигнатура. в библиотеке лежат связанные между собой функции и библиотека определяется набором функций.
Сигнатура функции- это как минимум ее имя, как максимум- имя, список и тип передаваемых параметров и версия. Как вариант- хранить хеш вместо сигнатуры. Иначе линковка не имеет смысла. Набор функций в либе тоже может меняться, но только если опять-таки есть возможность вырезать лишнее.

captain cobalt
17.10.2006, 15:52
Ну-ну. Никто не выказывал охоты перейти на существующий аласм, зато как только на горизонте нарисуется эфемерный компилятор, так все сразу побегут роняя тапки пользовать его и писать в нем програмы. Уж лучше использовать что есть. Ну так нужно писать совместимые с обоими подходами исходники или нет?

не в памяти, а на диске. соответсвенно когда задаем зависимости от библиотек указываем не только имя но и версию. и компоновщик грузит в память только нужную версию Вообразим себе программу, которая использует библиотеки A и B.
В свою очередь A использует C1.0, а B использует C2.0

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

captain cobalt
17.10.2006, 16:15
"Можно ли на спеке позволить себе держать ... в памяти?" :) нужное вставить Я объясню.

Есть код. Есть данные.
Чтобы код мог обрабатывать данные, они должны быть адресуемы одновременно.

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

Если хранить код в страницах, то он не сможет напрямую адресовать данные в других страницах.

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

Нижней памяти мало. Поэтому держать там дубли кода - недопустимо.

Верхней памяти гораздо больше. Особенно на клонах-монстрах. И использовать её для постоянного хранения конфигурационных данных с целью повышения кофморта работы - может быть вполне допустимо.

elf/2
17.10.2006, 16:17
Вообразим себе программу, которая использует библиотеки A и B.
В свою очередь A использует C1.0, а B использует C2.0
у нас уже есть многозадачность?


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


Единственное что полезное вытащил из идей captain cobalt'а- это версионирование на уровне функций, а не модулей целиком. Но это только если будет возможность раздербанивать библиотеки, вытаскивая нужные функции.
"версионировать" на уровне функции имеет смысл только если мы собираемся использовать одну функцию разных версий в одной программе. а этого надо избегать...

acidrain
17.10.2006, 16:25
Все тормоза перечислены.
Не видел, уточните! Напрасно голосновно заявляете - вам девушка привела кучу примеров, так что дерзайте - сравнивайте с амигой ваш писизм дальше. Только не забудьте на арм процессор (лучше тогда на ппц) сделать спек, чтоб шот как то работал с вашим писизмом и оопами и прочими попами :)

elf/2
17.10.2006, 16:28
Верхней памяти гораздо больше. Особенно на клонах-монстрах. И использовать её для постоянного хранения конфигурационных данных с целью повышения кофморта работы - может быть вполне допустимо.
к сожалению в услових критически малых ресурсов приходится думать в первую очередь об эффективности их использования, а не о комфорте работы. как я понимаю даже на клонах-монстрах памяти под пользовательские данные - мало. и отдавать одну-две страницы под парсеры/конфигурашки/реестры - это "преступная халатность" :)

acidrain
17.10.2006, 16:30
Я, конечно, дико извиняюсь, товарищ, но на все высказанные просьбы рассказать, в чем же есть круть несусветная амиги были получены однообразные ответы типа "смотрите libman, там все". Ну посмотрели, сделали выводы на основе неполной (уж сколько было) информации.
Ну во первых, вы девушек видели? С сисями такие? Они никак не товарищи, скорее подруги (amiga по испански :). Во вторых, ну сколько можно, товарищ Витамин С? Ну стормозили вы разок, не поняли, что я вам сказал, дык зачем на себя так долго дуться? простите себя уж! =)
Для того, чтобы объяснить вам - у ВАС должен присутствовать интерес, коего у вас нет. Во вторых объем информации не может быть умещен на данном форуме. Вам проеще скачать эмуль амиги и с нуля все исследовать самому - зацЕните. Обкакаете пц сразуже (не во всех отношениях кнешно8).
Я понимаю, что вам трудно все воспринять, но почитайте это (смотрю модеры тщательно удаляют все нужное?)
http://www.totalamiga.org/pdf/totalamiga_19.pdf
страницы 24-26. срочно! =)

captain cobalt
17.10.2006, 16:32
А реестр- это бред. Что именно?
Это ругательное слово?

А сам подход конфигурации автозагружаемых плагинов?

Vitamin
17.10.2006, 16:35
Ну во первых, вы девушек видели? С сисями такие? Они никак не товарищи, скорее подруги (amiga по испански . Во вторых, ну сколько можно, товарищ Витамин С? Ну стормозили вы разок, не поняли, что я вам сказал, дык зачем на себя так долго дуться? простите себя уж! =)
Когда я обращаюсь к девушкам "мадам", никто не обижается и не считает себя "французской шлюшкой", так что я перешел на сугубо нейтральный тон.
И на себя я не дуюсь, я вообще ни на кого не дуюсь долго- надоедает быстро %)
Я конечно понимаю, что обидел ее просьбой привести подтверждение своим словам, но, следует заметить, мы тут постоянно друг друга так обижаем, а с тобой лично так через пост прям %))

acidrain
17.10.2006, 16:39
мы тут постоянно друг друга так обижаем, а с тобой лично так через пост прям
да не, ты меня не обижал =) читай пост №217 еше раз, ок? =)

captain cobalt
17.10.2006, 16:43
у нас уже есть многозадачность? В примере - одна программа.
Ведь могут одни библиотеки использовать другие?

Не видел, уточните! 1. Надо загрузить в регистр хэндл библиотеки.
2. Косвенный переход медленнее.
3. Регистр недоступен для передачи аргумента.

к сожалению в услових критически малых ресурсов приходится думать в первую очередь об эффективности их использования, а не о комфорте работы. как я понимаю даже на клонах-монстрах памяти под пользовательские данные - мало. и отдавать одну-две страницы под парсеры/конфигурашки/реестры - это "преступная халатность" :) У меня другое мнение.

Вон какие RAM-диски себе отгрохали. И всё ради комфорта работы. :)
По сравнению с этим одна страница - ерунда.

elf/2
17.10.2006, 16:51
В примере - одна программа. Ведь могут одни библиотеки использовать другие?
извиняюсь, невнимательно прочитал :(

однако, иметь несколько версий одной библиотеки на диске - это суровая необходимость. иначе получим неработающие программы (тот самый dll hell)

Vitamin
17.10.2006, 16:55
да не, ты меня не обижал =) читай пост №217 еше раз, ок? =)
Ну как это не обижал? Постоянно требовал аргументации %)

А по поводу поста 217- ссылку занотил, почитаю позже. Скачать эмуль и погонять его не имею возможности- просто физически некогда.
(шепотом) А что, модеры удаляют отсюда посты? Наверное столько мусора уже скопилось, что удаление одной-двух кучек особо не заметно...

Возвращаюсь еще раз к теме амиги. Посколько я про нее не знаю, а изучать нет возможности, буду задавать конкретные вопросы тебе. Идет?

captain cobalt
17.10.2006, 17:07
однако, иметь несколько версий одной библиотеки на диске - это суровая необходимость. иначе получим неработающие программы (тот самый dll hell) Моя позиция:
1. Каждая библиотека должна быть одна. На диске и в памяти.
2. Нужен контроль целостности.
3. Если совместимость достаточна - должно компоноваться.
4. Всё остальное - проблемы программистов.

elf/2
17.10.2006, 17:20
Я понимаю, что вам трудно все воспринять, но почитайте это (смотрю модеры тщательно удаляют все нужное?)
http://www.totalamiga.org/pdf/totalamiga_19.pdf
страницы 24-26. срочно! =)
пока злобные модеры не потерли, бросился читать... если в двух словах, то очень похоже на COM :), только менее гибкое поскольку в runtime нельзя узнать список интерфейсов поддерживаемых библиотекой и похоже список функций для конкретного интерфейса жестко прошит в header'ах. хотя на основании только этой статьи утверждать не буду.

расстраивает, то что даже для использования базовой функциональности (Intuition - это GUI? я не ошибся?) приходится делать кучу телодвижений:
1. открыть либу
2. получить интерфейс

попользоваться...

3. отдать интерфейс
4. закрыть либу

структура самой программы напоминает то что рекомендовала MS во времена Windows 3.11, тот же цикл ожидания сообщений, тот же разлапистый switch-case внутри

зы: только без обид пожалуйста, сами ссылку предложили

elf/2
17.10.2006, 17:23
1. Каждая библиотека должна быть одна. На диске и в памяти.
2. Нужен контроль целостности.
3. Если совместимость достаточна - должно компоноваться.
4. Всё остальное - проблемы программистов.
есть старая, но очень нужная программа требующая main.lib.1.0
поставили новую программу, которой нужна main.lib.10.4

как программист может эту проблему решить?

acidrain
17.10.2006, 17:29
Возвращаюсь еще раз к теме амиги. Посколько я про нее не знаю, а изучать нет возможности, буду задавать конкретные вопросы тебе. Идет?
Задавай, и задавай девушке Лене (хорошо прошаренной не только в амиге, но и пц и zx) - думаю она компетентно ответит...

Vitamin
17.10.2006, 17:35
Задавай, и задавай девушке Лене (хорошо прошаренной не только в амиге, но и пц и zx) - думаю она компетентно ответит...
Ок. Вопросы возможно ранее уже здесь звучали, но ответ на них я или не увидел или пропустил
Тебе (все про амигу):
-поддерживается ли взаимная работа модулей- импортирование-экспортирование функций
-поддерживаются ли экспорт/импорт данных
раз вопрос релокации там не стоит, другой вопрос
-интерфейсы жестко прописаны в виде индексов функций. символические ссылки есть?
может быть, я задаю вопросы без понимания тонкостей структуры и организации, если получится, попробуй воспользоваться параллелями с существующими разработками на том же пц.

Лене:
-я все еще жду ответа на тему автоматического исключения неиспользуемых функций при компиляции с помощью аласма :)
-если есть возможность, можно ответить на вопросы к acidrain

acidrain
17.10.2006, 17:44
структура самой программы напоминает то что рекомендовала MS во времена Windows 3.11, тот же цикл ожидания сообщений, тот же разлапистый switch-case внутри
Не знаю, как там с виндовз - я в виндовз (из вредности и пристрастия к амиге и спеку) никогда не кодил (не считая пару сишных прог для моего покетпц).
То, что в этой статье написано - справедливо для ОС4, а мы обсуждаем ОС3.9. тут несколько иначе (кстати в статье об этом сказанно). Как там хеадерами и прописанными ифейсами - хз, не кодил. Но т.к. уже модуль какой то настряпан автором треда - то думаю обсуждение не уместно.
Давайте немного отдалимся от ооп и современных методах прогинга и пойдем старым, дедовским способом?
Сначала я воспринял предложение Витамина так, что будет некий типа бут, который займется загрузкой либл и прог и их распределением в памяти (то, что я делал на спеке, до окончания универа - после я забросил сие велеколепное дело). Посему посчитал абсурдным линковку и тем более запрос ифейсов и прочее. Разве не разумнее иметь либлы на диске и всего 2-3 открытых для прог в один момент времени. Т.к. о многозадачности не шло речи, то распределение памяти, упраление открытием-закрытием либл вполне мог на себя загрузчик. Одна либла - графический интерфейс (ГУИ), графическая либла (? не вижу необходимости для спека). Возможно математическая либла. Что еще может понадобиться? Управление клавой? Мышью? Все это в ехес (керналь-загрузчик). Итого, мы имеем реально 1 либлу для прог.
Выход из проги ессно в бут (или что там будет). Ествественно все это обрастет со временем. больше никаких изысков.
Для программера будет еще проще - список входов в инклудах(.h, .i) и autodoc's. Единственное что - релокация, но с этим справится загрузчик и прога пост-компилятора для создания таблицы релокации.
Пока все, пора бежать

GriV
17.10.2006, 18:01
Уважаемый captain cobalt, скажите, вы вживую видели 'подход библиотек Амиги'? Я что-то сомневаюсь... Вы вон давеча ажно драйвер памяти аласма записали в ООП или куда там. Признайтесь, вы даже его в глаза не видели?!

Давайте поосторожней, всё-таки у нас клуб друзей...


Был предложен вариант динамической линковки со статически распологаемой (по указанному программой адресу) таблицей входа (JP func1:JP func2:...). Данный вариант позволяет писать программы 'как обычно', с единственной проблемой - распределением памяти под разные библиотеки. Также есть вариант libman примерно с аналогичной функциональностью, за исключением принципа вызова. Но нет же, вам подавай писизм, с обязательным исправлением абсолютных адресов везде, где только можно! Ну ничего, время лечит...

Во-первых, то что вы предлагаете, это не есть что-то новое и для спектрума в частности - такая древня игра как "Strip Poker 2+" - я её ломал - использовала именно такой подход. А если посмотреть, например, http://zx.pk.ru/showthread.php?t=1811, то вы увидите, что это всё уже обсуждалось и флеймилось не раз.


А ничего, что с любой линковкой в рунтайм будут тормоза не с компиляцией, а каждый раз - с загрузкой и линковкой? Или вы во имя идеалов писизма готовы пожертвовать чем угодно, в том числе и удобством пользователей?

Пока что я вижу идеалистов от амиги а не идеалы от писизма. В нашей среде (имею в виду спектрумистов) это очень тяжкое оскорбление, думаю вы извинитесь перед captain cobalt за незаслуженное обвинение.


Скажите, а что вы будете использовать, если вы захотите написать 50fps вьювер, игрушку с выводом спрайтов через стек и кучей 256b-aligned таблиц, мультиколорную или чанковую дему, наконец? Ваш подход - опять же отдаёт писизмом, он не позволяет на СИЛЬНО ОГРАНИЧЕННЫХ ресурсах Спектрума делать действительно быстрые и крутые вещи. Если только лишь тошнить стандартными процедурами уровня инфоркома (помните, были ещё книжки - 'как написать игру на ассемблере' или 'динамическая графика') с кучей заморочек насчёт линковки, ооп и проч. пурги - то и получатся тошные программы - медленные, неинтересные.

В том то и дело, что ежели сей код можно уложить в пределах одной страницы, то можно написать библиотеку - и это будет отлично работать, потому что переходы к этой библиотеке, выраженной в виде модуля и впоследствии собранной линковщиком, будут простым Call или Jp. Как раз это и позволяет реализовать на сильно ограниченных ресурсах хорошие программы - потому что библиотеки будут разрабатываться (в теории конечно, если всё хорошо пойдёт...) коллективом из нескольких (надеюсь десятков) человек. В итоге как вы не пляшите, для вывода мультиколоров вы будете пользоваться
pop hl
ld (XXXX),hl
или
ld hl,YY
push hl
И почему бы генератор сего кода не сделать универсальным? тогда останется лишь набрать строчку типа
call ScrMulti.Generate
да вызов
ld hl,<адрес картинки>
call ScrMulti.Show
и всё.
Да, есть такие случаи которые нельзя стандартными библиотеками охватить, но читайте внимательно - я уже про это писал - это около 1% всех случаев программо-производства.


За каждой из программ тянется шлейф похожих (на процедуры в других программах) процедур, и если это не те программы, от которых тошнит, а реально быстрые вещи, то каждая процедура вылизана десятки раз и адаптирована именно под конкретный случай применения. Зачем тут некие стандартные библиотеки (модули - называйте, как хотите) с 'swiss-knife type'-процедурами на все случаи жизни, с обработкой всех возможных ситуаций и тонной вариантов действий?

ВЫ сами себе противоречите - то вы говорите что библиотечный подход фигова, а библиотеки отлаженный многократно проверенный и не единожды пользуемый код, то говорите что нужно пользоваться отлаженным кодом (противопостоявляя первое второму). Вы всё-таки определитесь, что нам хорошо а что плохо.


Это технология чтения аргументов, 'вшитых' в машинный код, т.е. неизменяемых. И опять же, чтения в регистры, а не использования. Для комфортного их использования (несколько раз и в нужные моменты) их придётся переложить в память, по IX/IY ли, в абсолютную ли (по адресу). Немаловажно и то, что такие аргументы (вшитые в код) затрудняют отладку программы (не ясно, сколько таких аргументов идёт после CALL и когда они кончаются и начинается дальше код, к тому же дизассемблер воспримет их как код, выдав бессмысленные команды).

Я к вам лично обращаюсь и прошу вначале ознакомиться с модульной структурой и потом уже такое выдавать.


Вы в жизни не видели процессоры архитектуры 68к, вам мало 15 32-битных регистров? Это вам не х86, где каждый регистр на вес золота.

Это какой то оффтоп, здесь речь идёт, напомню, про спектрум и про Z80.


Здесь начинается гибкость против скорости. Гибкость может быть очень полезной штукой на практике. Скорость же в стиле "демо на посмотреть один раз" может имет гораздо меньшее значение. Ибо "пиксели Спектрума никого не плющат".

+1


Модули не "вставляются" в программу.
Программа загружается поверх библиотечных модулей.
Когда программа завершается, модули остаются и не трогаются.
Теперь поверх них можно загрузить другую программу.

Всё-таки вы не прочитали по модули, потомы вы такое говорите.


Заменим слово "модули" на слово "ОС".
ОС "вставляется" в программу? Нет.
ОС можно отделить от программы? Можно.
Тогда зачем нужно "свойство модульной структуры"?

Какая то софистика...
Я совсем не про это вам говорил.
Прежде всего, если ктото хочет многократно пользоваться одним модулем, находящимся резидентно в памяти, то нужна система управления модулями - централизованная - которой будут подчиняться все приложения. Это попахивает целой операционной системой (как это кстати и стало в iSDOS).
Модуль это ГОТОВАЯ программа с точками экспорта, когда она внедрена компоновщиком, то она стала единым целым с программой-инициализатором и отодрать её от программы это сродни пытаться выдрать черенок плодонесущей яблони из дички после того как они 10 лет вживались - вы просто убьёте и то и другое без какого-либо результата. Это не плагинная система, это система пользования готовыми пользовательскими библиотеками.


Это опять "дух процедурного программирования".

Функциональностью не обязательно пользоваться явно.

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

Что мы с вами друг друга не понимаем - я вам про яблоки вы мне про дрова. Программа она есть и законечена, в качестве одной из библиотек может быть реализация плагинной системы, но плагины и библиотеки - это разные вещи. Условно - без библиотек программа не запуститься - потому что это её часть и её кровь, программа точно знает какие библиотеки надо подгрузить; без плагинов обычно программы работают и плагины в основном нужны для увеличения функциональности программы на основе непредсказуемого заранее объёма дополнительно используемых кусков кода.


тогда надо было начинать с рассказа о том что уже есть и как это работает. и обязательно объяснить чем это лучше/удобнее других методов.

Кажется я пытался это сделать, жаль что столь безуспешно...


Я тоже было подумал, что черная кошка пробежала дважды, но ты меня опередил %)

Единственное что полезное вытащил из идей captain cobalt'а- это версионирование на уровне функций, а не модулей целиком. Но это только если будет возможность раздербанивать библиотеки, вытаскивая нужные функции. В противном случае это не имеет смысла.

Это значит каждую точку внешнего вызова сопровождать версией?.. но это такое... своеобразное увлечение, боюсь лучше (и гораздо лучше) делать major minor редакции библиотек, а компилятору это учитывать.


Вообразим себе программу, которая использует библиотеки A и B.
В свою очередь A использует C1.0, а B использует C2.0

В любом случае эта программа будет на совести программиста который её писал. Обычно комплект библиотек не являются внутри себя противоречивым, а значит и "кривые" модули будут связаны с криворукостью писавшего текст. Кроме того, если библиотека С версии 1.0 и 2.0 представлена в виде отдельных файлов то ничто не помешает ими пользоваться одновременно - потому что в итоге это будет машкод после сборки.


у нас уже есть многозадачность?

Хочу уверить что есть и очень хорошая - кооперативная с механизмом псевдовытеснения.

GriV
17.10.2006, 18:03
Не видел, уточните! Напрасно голосновно заявляете - вам девушка привела кучу примеров, так что дерзайте - сравнивайте с амигой ваш писизм дальше. Только не забудьте на арм процессор (лучше тогда на ппц) сделать спек, чтоб шот как то работал с вашим писизмом и оопами и прочими попами

Жаль что я не увидел кучи примеров. Между прочим ярым писизмом/амигизмом занимаются тут всего несколько человек, жаль что их голоса столь отчётливо слышны... Кидаетесь терминами, хоть попытайтесь обосновать вашу точку зрения словами отличными от "это жалкий писизм" "ооп" и прочими из того же ряда.


Ну во первых, вы девушек видели? С сисями такие? Они никак не товарищи, скорее подруги (amiga по испански

Видимо такие не встречаются в таганроге и в набережных челнах.
И вообще я считаю это очень своеобразным и локальным явлением...


Вам проеще скачать эмуль амиги и с нуля все исследовать самому - зацЕните. Обкакаете пц сразуже

Простите, а на какой платформе запускать эмулятор амиги? На ZX? Или На x86? Тогда это что - оффтоп? И при чём тут амига? Как вообще эмулятор амиги связан с текущим обсуждением?


Задавай, и задавай девушке Лене (хорошо прошаренной не только в амиге, но и пц и zx) - думаю она компетентно ответит...

Опять оффтоп?


я в виндовз (из вредности и пристрастия к амиге и спеку) никогда не кодил

Тогда очень неправильно с вашей стороны рассуждать о проблемах и преимуществах написания программ под x86


Одна либла - графический интерфейс (ГУИ), графическая либла (? не вижу необходимости для спека). Возможно математическая либла. Что еще может понадобиться? Управление клавой? Мышью? Все это в ехес (керналь-загрузчик).

Какая мышь, какой GUI? Математическая возможна только гипотетически???? Вы вроде про спектрум говорите? Я тут уже указывал специально для вас список нужны библиотек, жаль что вы это просмотрели (или не успели прочитать, как угодно). Поищите, на 16й странице сего треда. Если есть возражения по поводу списка давайте свой.

acidrain
17.10.2006, 18:36
Тогда очень неправильно с вашей стороны рассуждать о проблемах и преимуществах написания программ под x86
Так заявлять - это не правильно с вашей стороны. вы не знаете, что такое программирование под покетпц? Тогда в сад. Это и есть винда, только урезанная, не смотря на то, что она на арме функционирует.

acidrain
17.10.2006, 18:40
1. Надо загрузить в регистр хэндл библиотеки.
2. Косвенный переход медленнее.
3. Регистр недоступен для передачи аргумента.
1. +3.
Код:
lea GFXname(pc),a1
jsr -$228(a6) ; OpenLibrary()
Сколько вам надо регистров для передачи данных? 1 регистр из 16 32 битных доступных на момент перехода - это много?
2. кто вам сказал? это не з80 и не х86.

acidrain
17.10.2006, 18:52
Видимо такие не встречаются в таганроге и в набережных челнах.
И вообще я считаю это очень своеобразным и локальным явлением...
мне вас искренне жаль 8)


Цитата:
Сообщение от acidrain
Вам проеще скачать эмуль амиги и с нуля все исследовать самому - зацЕните. Обкакаете пц сразуже


Простите, а на какой платформе запускать эмулятор амиги? На ZX? Или На x86? Тогда это что - оффтоп? И при чём тут амига? Как вообще эмулятор амиги связан с текущим обсуждением?

Дочитали до конца? Если объем требуемой инфы превышает возможности этого форума, то как вы прекажите выложить инфу? - ищите. ведь для пц вы нашли? и для амми ее полно.



Цитата:
Сообщение от acidrain
Одна либла - графический интерфейс (ГУИ), графическая либла (? не вижу необходимости для спека). Возможно математическая либла. Что еще может понадобиться? Управление клавой? Мышью? Все это в ехес (керналь-загрузчик).


Какая мышь, какой GUI? Математическая возможна только гипотетически???? Вы вроде про спектрум говорите? Я тут уже указывал специально для вас список нужны библиотек, жаль что вы это просмотрели (или не успели прочитать, как угодно). Поищите, на 16й странице сего треда. Если есть возражения по поводу списка давайте свой.[/QUOTE]
Нет, ну ты попридираться? Я сказал, что мне пора бежать - все уложил в несколько строк в спешке. То, что ты предложил, мною было повторено (не отрицай - все тоже самое. я не могу постоянно следить за форумом), за исключением доса. чуть не забыл ;) добавим еще dos.library.
Ну зачем для токой системы городить огород в виде вашей линковки и прочего?
Вы конструктивно, без язвлений прокомментируйте, то, что я написал в том посте.
Ведь конструктивизма 0. Прочтите еще раз, скажите, где я не прав?

Vitamin
17.10.2006, 19:09
Прочтите еще раз, скажите, где я не прав?
Неправ в том, что отрицая то, что УЖЕ имеется, ничего не предлагаешь взамен. Потому что твои предложения из серии "а вот на амиге..." (притом что пц ближе к спеку как по доступности, так и по архитектурным соображениям) или морально устарели, поскольку не обеспечивают должного функционала.

Напоминаю про пост 228 (и не только тебе)

icebear
17.10.2006, 19:38
А что, модеры удаляют отсюда посты? Наверное столько мусора уже скопилось, что удаление одной-двух кучек особо не заметно...

Видать база снова рухнула и закатали бэкап. Посмотри на счётчик написаных сообщений у себя. Я не досчитался где-то 70-ти штук.

captain cobalt
17.10.2006, 19:39
Всё-таки вы не прочитали по модули, потомы вы такое говорите. Я лишь высказываю идею.
Вон, Vitamin говорит что "не противоречит".

Какая то софистика...
Я совсем не про это вам говорил.
Прежде всего, если ктото хочет многократно пользоваться одним модулем, находящимся резидентно в памяти, то нужна система управления модулями - централизованная - которой будут подчиняться все приложения. Динамический компоновщик.
Загрузчик.
Что ещё нужно?

Модуль это ГОТОВАЯ программа с точками экспорта, когда она внедрена компоновщиком, то она стала единым целым с программой-инициализатором и отодрать её от программы это сродни пытаться выдрать черенок плодонесущей яблони из дички после того как они 10 лет вживались - вы просто убьёте и то и другое без какого-либо результата. Попробуем объяснить иначе.

Одни модули используют другие модули. Все модули в целом образуют иерархию. Модули более высокого уровня зависят от модулей нижних уровней. Но модули нижних уровней не зависят от модулей высших уровней. Программа зависит от библиотеки. Но библиотека не зависит от программы.

Если так будет понятнее, мы можем пронумеровать уровни иерархии. Вот например в iS-DOS "уровни ядра" - пронумерованы. И имеется документированный способ выгрузить несколько верхних уровней, чтобы освободить память. Некоторые тяжёлые программы делают. При этом нижние уровни не умирают.

Теперь пусть у нас есть динамический компоновщик. Всё точно так же. Только "ядро" и "уровни" не нужны, а есть просто модули.

В любом случае эта программа будет на совести программиста который её писал. Обычно комплект библиотек не являются внутри себя противоречивым, а значит и "кривые" модули будут связаны с криворукостью писавшего текст. Кроме того, если библиотека С версии 1.0 и 2.0 Дело было так.
Когда программист писал свою программу, библиотека B использовала C1.0.

И только после этого разработчики B выпустили новую версию, совместимую с предыдущей, но использующую C2.0. Программист не виноват.

Именно в этом смысл этого примера.
Совместимость по версии на один уровень нетранзитивна на несколько уровней.

Хочу уверить что есть и очень хорошая - кооперативная с механизмом псевдовытеснения. Нужен пресс-релиз для народа. :)

GriV
17.10.2006, 20:03
Так заявлять - это не правильно с вашей стороны

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


Дочитали до конца? Если объем требуемой инфы превышает возможности этого форума, то как вы прекажите выложить инфу? - ищите. ведь для пц вы нашли? и для амми ее полно.

Я против оффтопа, а вы продолжаете его развивать, какой нафик ООП, какой CALL по смещению? Это не спектрум и никогда им не будет. Вопрос не в том, что лучше - амига или пэцэ, вообще не понимаю, какое это имеет отношение к предмету обсуждения (так же как эмуляторы и прочая), если вы имеете сказать что вот конкретно этот элемент, принятый в библиотечном программировании на другой платформе имеет явный позитив если его использовать в модульной структуре предложенной витамином, тогда это будет конструктивным, всё остальное я считаю оффтопом и это так по определению.
Прошу заметить, хоть я не согласен с мнением Captain Cobalt, у него отсутствует оффтоп в этой теме - он хоть со своей точки зрения но предлагает модификации текущей структуры модулей (это я и называю конструктивом).


Нет, ну ты попридираться? Я сказал, что мне пора бежать - все уложил в несколько строк в спешке.

Я не придираюсь, я прошу быть внимательным и прежде чем отвечать посмотреть всю тему до конца. Если это для вас является сложным, тогда наверное не имеет смысл браться участвовать в обсуждении темы. Первый раз я эту тему начал читать вчера, и прежде чем написал свой ответ, я прочитал ВНИМАТЕЛЬНО все 16 страниц уже существующего треда. Если вы торопитесь то потерпите, выберите какой-то отрезок своего времени, чтобы можно было прочитать всё и разобраться с тем, что написано, а только потом отвечайте. Тред никуда не убежит и ни одна ценная идея не канет в лету.


Вы конструктивно, без язвлений прокомментируйте, то, что я написал в том посте.
Не пытался язвить, если вас обидел, извините я это сделал ненарочно
Я не очень понимаю на какое ваше сообщение вы ссылаетесь, но попытаюсь предположить.
Я считаю что библиотеки должны в себя включать обыкновенные повседневные процедуры, к коим ГУИ и прочее что вы описали не относятся. Вы что - при написании программы в первую очередь дёргаете мышиный интерфейс и ГУИ? Я думаю вы сами знаете ответ.

P.S. 2acidrain> Очень неприятно когда передёргивают мои ответы и сообщения выдернутые из контекста. Ещё неприятней, когда на явно заданные вопросы не получаешь ответа. Я стараюсь ответить на все вопросы ко мне, в который раз приходиться только сожалеть что это не симметрично...

captain cobalt
17.10.2006, 20:09
2. кто вам сказал? это не з80 и не х86. Хорошо.
Система команд действительно лучше подходит для таких вызовов.

Зато NOP - и тот два байта. :) И команды имеют разную длину. :)

Короче.
Такой подход плохо подходит для "убогих процессоров". Правильно? Тогда зачем столько разговоров о нём.

Сколько вам надо регистров для передачи данных? 1 регистр из 16 32 битных доступных на момент перехода - это много? Значение регистра убивается.
Необязательно именно передавать аргумент.
Может мы хотели просто, чтобы в нём хранилось число и не испортилось от вызова.

GriV
17.10.2006, 20:10
библиотека B использовала C1.0.

Да, пример я понял
Тем не менее, можно при помощи модульной структуры и этот момент обойти - кажется здесь уже говорилось про это - собрать модуль А с С1.0 и В с С2.0 - в итоге выйдет два модуля - расширенный А и расширенный В, причём естественно что такого рода изврат нужен только в случае, если кто-то нарочно или нет спровоцировал указанный развал библиотек по версиям.


Только "ядро" и "уровни" не нужны, а есть просто модули.

В том то и дело, что простая система-компоновщик может перерасти в целую систему, как это было с ис-досом (вот и вы на него ссылаетесь), витамин же предлагает просто систему облегчения стараний.


Я лишь высказываю идею.
Вон, Vitamin говорит что "не противоречит".

Тогда это конструктив %-)))))))

captain cobalt
17.10.2006, 20:34
есть старая, но очень нужная программа требующая main.lib.1.0
поставили новую программу, которой нужна main.lib.10.4

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

Ещё раз вспоминаем, что на спеке почти весь код вылизан. Нужно лишь закатать его в библиотеки.

Ответ на вопрос - нужно исправлять "старую программу".

я все еще жду ответа на тему автоматического исключения неиспользуемых функций при компиляции с помощью аласма :) В моих материалах ничего нет. А что говорит maintainer?

Зато такое уже лет десять есть в ZXASM:
Наиболее полезна директива IFUSED,
которая позволяет создавать библиотеки
подпрограмм в исходных ассемблерных
текстах, так что из всей библиотеки
скомпилированы будут лишь те подпрог-
раммы, к которым осуществлялось обра-
щение.

captain cobalt
17.10.2006, 21:10
собрать модуль А с С1.0 и В с С2.0 - в итоге выйдет два модуля - расширенный А и расширенный В Ого!

А когда одна версия C, можно ли если граф импорта имеет склеенные ветки, собрать результат с одним экземпляром C?
А, Vitamin? :)

acidrain
17.10.2006, 21:16
(притом что пц ближе к спеку как по доступности, так и по архитектурным соображениям) или морально устарели, поскольку не обеспечивают должного функционала.
Загнул! Устарели? Говрю ж (даже статью привел), что развивается, не устарело. Давай реально проведи аналогии с пц и спеком.
Теперь задумайся вот над чем. Амига появилась в 1985 году. В ее распоряжении были: 7,14мгц проц, чипсет. Но при этом все это дело рабоало и работает в разы шустрее чем на пц. Где была винда в 85? Как она выглядела? Что у нее были за либлы? А на амиге были уже реальный мультитаскинг, пресловутый autoconfig (который на пц появился в виде плугандплай в 90е годы) и мультимедиа. Все это на 7 мгц!
Как же вы собираетесь на спеке реализовать функционал с пц? есть ресурсы?

acidrain
17.10.2006, 21:20
Зато никогда не скажу что на амми покетпэцэ или ещё где галимый формат библиотек и кривая методика программирования, жаль что это не симметрично....
КОГДА я заявлял, что на пц голимый формат либл? Или в линухе? Вам почудилось! Я утверждаю, что надо думать иначе, а не как все. Вы все думаете как на пц. А некоторые видят, как это реализовать не ориентируясь на пц. И менее ресурсоемкое.

acidrain
17.10.2006, 21:22
я прошу быть внимательным
и тебя тоже. ты так ит не ответил на поставленный вопрос. Я не читаю чушь про ооп на спеке и прочее. мне и так есть чем заняться.
Я не слышал от тебя вопроса. Вопросы от витамина - он не читает, что ему пишут. упорно продолжает твердить. а в посте http://zx.pk.ru/showpost.php?p=61553&postcount=229 я написал, что отойдем от пц и амиги. вынес предположение о том, как я понял витамина и как хотел бы это видеть на спеке. Но от тебя последовали придирки и явное игнорирование всего того, что там написано.
Там сказанно, что зачем динамические компоновщики, когда можно проще. Жду ответа. Под гуи я подразумевал именно intuition интерфейс для создания окон и примитивных гаджетов. Из наших списков расход был лишь в том, что мышь и клаву я предложил, а ты только клаву.

captain cobalt
17.10.2006, 21:42
А некоторые видят, как это реализовать не ориентируясь на пц. И менее ресурсоемкое. Более ресурсоёмкое во время выполнения. Доказано.

Теперь можно лишь сравнить ресурсоёмкость компоновки. Если бы мы вообще не смогли дождаться окончания компоновки - это была бы проблема. :) Но это не так. А после компоновки мы можем наслаждаться быстрым кодом.

Есть другие факты кроме "видений ресурсоёмкости"?

GriV
17.10.2006, 21:49
А когда одна версия C, можно ли если граф импорта имеет склеенные ветки, собрать результат с одним экземпляром C?
А, Vitamin?

Это был вариант технического решения, в общем программист не должен заботиться вопросами библиотек и их версий, в спецификации к существующим библиотекам должна указана быть требуемая версия библиотек.
Если первичный уровень - вызывающий не пользуется C ему пофигу как будут склеены A и B, я имел в виду только это.


Теперь задумайся вот над чем. Амига появилась в 1985 году.

Если вы будете продолжать таким образом, я пожалуюсь модераторам на то, что вы слишком много оффтопите - почти каждое ваше сообщение имеет указания на Амигу или ПЦ, хватит уже.


КОГДА я заявлял, что на пц голимый формат либл? Или в линухе? Вам почудилось! Я утверждаю, что надо думать иначе, а не как все. Вы все думаете как на пц. А некоторые видят, как это реализовать не ориентируясь на пц. И менее ресурсоемкое.

И снова ПЦ, и снова ничего по существу.


и тебя тоже. ты так ит не ответил на поставленный вопрос

Я ответил на вопрос, почитайте внимательней. Если же я ответил не на тот вопрос, это ваша вина - так мне его вы адресовали.


Я не слышал от тебя вопроса. Вопросы от витамина - он не читает, что ему пишут. упорно продолжает твердить


Простите, а на какой платформе запускать эмулятор амиги? На ZX? Или На x86? Тогда это что - оффтоп? И при чём тут амига? Как вообще эмулятор амиги связан с текущим обсуждением?

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


а в посте http://zx.pk.ru/showpost.php?p=61553&postcount=229 я написал

Я раз 10 перечитал это пост, так и не понял там ничего, на самом деле видимо спешили и не успели мысль свою оформить, потому может быть вы объясните ваше предложение?


написал, что отойдем от пц и амиги

Хым... а кто шёл к ПЦ и амиге?


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

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

acidrain
17.10.2006, 21:53
-поддерживается ли взаимная работа модулей- импортирование-экспортирование функций
-поддерживаются ли экспорт/импорт данных
раз вопрос релокации там не стоит, другой вопрос
-интерфейсы жестко прописаны в виде индексов функций. символические ссылки есть?
может быть, я задаю вопросы без понимания тонкостей структуры и организации, если получится, попробуй воспользоваться параллелями с существующими разработками на том же пц.
1 - модуль? какой экспорт? куда?
2 - куда? если ты про сигналы и сообщения то запросто. http://www.totalamiga.org/pdf/totalamiga_18.pdf страницы 24-26 немного затрагивают сей вопрос.
3 - только супер прошаренные программеры типа Stingray могут помнить все входы либл по смещениям. А все остальные (я в т.ч.) пользуются инклудами, хеадерами. См. также архив. он не полный. думаю больше не надо. разумный человек поймет что к чему. Это инклуды для асма. для си не шлю - не особо разнятся.
И исходник, что было видно, как применять.

acidrain
17.10.2006, 21:54
Доказано.

Досей чтоли? Небыло доказательств - только голословные. Чем быстрее в винде?

captain cobalt
17.10.2006, 21:58
Там сказанно, что зачем динамические компоновщики, когда можно проще. Жду ответа. Процитирую себя из другой ветки:

1. Релоцируемость - это пропатчивание CALL относительно базы своего модуля
2. Динамическая компоновка - это пропатчивание CALL относительно базы другого модуля Если на Амиге есть релокация, то почему нету динамической компоновки, а вместо неё "загрузчики" и "пост-компиляторы"?