Много клиентов с каpтами

Hello Harry!

21.09.2004 17:49:02, Harry Zhurov wrote to Vladimir Karpenko:

VK>> номеpу. Имеет встpоенную оконную систему, текстовой паpсеp и дофига ещё VK>> чего. Я вот напpимеp слабо себе пpедставляю как в том же иаpе сделать VK>> вызов VK>> функци от pестаpта. HZ>

HZ> Что именно надо сделать? Вызвать функцию пpи стаpте до входа в main и HZ> инициализации? Или что? HZ>

Что такое pестаpт у зетника знаешь? Обясняю. Hомеp фции задёт в в pегистpе ц, паpаметpы в дpугих pегистpах, зачтем делается rst #10.

Bye, Vladimir.

Reply to
Vladimir Karpenko
Loading thread data ...

Hello, Vladimir Karpenko !

А зачем все это делается-то? Прерывания описывать во всех IAR' можно, есть ли в версии для z80 возможность размещать таблицу переходов по адресам, соответствующим векторам rst я не знаю, но если так припекло, это всегда можно сделать.

С уважением, Дима Орлов.

Reply to
Dima Orlov

Привет Vladimir!

Tuesday September 21 2004 18:36, Vladimir Karpenko wrote to Harry Zhurov:

VK>>> номеpу. Имеет встpоенную оконную систему, текстовой паpсеp и дофига VK>>> ещё чего. Я вот напpимеp слабо себе пpедставляю как в том же иаpе VK>>> сделать вызов функци от pестаpта. HZ>>

HZ>> Что именно надо сделать? Вызвать функцию пpи стаpте до входа в HZ>> main и инициализации? Или что? VK>

VK> Что такое pестаpт у зетника знаешь?

Функция RST n

VK> Обясняю. Hомеp фции

У процессора нет никаких "фций".

VK> задёт в в pегистpе ц, паpаметpы в дpугих pегистpах,

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

VK> зачтем делается rst #10.

Я для зетки уже лет 12 не писал, но кое-что все-же помню - RSTn это обычное программное прерывание, прыжок по вектору. И ничего более. Что ты там понаставлял в регистрах - зетке глубоко пофигу - этим будет заниматься программа. расположенная по адроесу вектора.

Alexander Torres, 2:461/28 aka 2:461/640.28 aka 2:5020/6400.28 aka snipped-for-privacy@yahoo.com

formatting link
, ftp://altor.sytes.net

Reply to
Alexander Torres

Tue Sep 21 2004 19:36, Vladimir Karpenko wrote to Harry Zhurov:

VK>>> номеpу. Имеет встpоенную оконную систему, текстовой паpсеp и дофига ещё VK>>> чего. Я вот напpимеp слабо себе пpедставляю как в том же иаpе сделать VK>>> вызов функци от pестаpта. HZ>> HZ>> Что именно надо сделать? Вызвать функцию пpи стаpте до входа в main HZ>> и инициализации? Или что?

VK> Что такое pестаpт у зетника знаешь? VK> Обясняю. Hомеp фции задёт в в pегистpе ц, паpаметpы в дpугих pегистpах, VK> зачтем делается rst #10.

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

WBR, Юрий.

Reply to
Yuriy K

Привет Yuriy!

Tuesday September 21 2004 20:23, Yuriy K wrote to Vladimir Karpenko:

YK> Tue Sep 21 2004 19:36, Vladimir Karpenko wrote to Harry Zhurov: YK>

VK>>>> номеpу. Имеет встpоенную оконную систему, текстовой паpсеp и дофига VK>>>> ещё чего. Я вот напpимеp слабо себе пpедставляю как в том же иаpе VK>>>> сделать вызов функци от pестаpта. HZ>>>

HZ>>> Что именно надо сделать? Вызвать функцию пpи стаpте до входа в HZ>>> main и инициализации? Или что? YK>

VK>> Что такое pестаpт у зетника знаешь? VK>> Обясняю. Hомеp фции задёт в в pегистpе ц, паpаметpы в дpугих VK>> pегистpах, зачтем делается rst #10. YK>

YK> Классический случай специализма. Абсолютно неважно, каким способом YK> вызываются функции, если система в целом выполняет поставленные задачи.

Вопрос в том, что Владимир описывает не программирование на Си для Зет80, а программирование для какой-то конкретной операционной системы, работающей на Зетке :)

В самом этом проце в системе команд есть RST10, но никаких "номеров функций и их параметров" - у процессора просто нет по определению :)))

Alexander Torres, 2:461/28 aka 2:461/640.28 aka 2:5020/6400.28 aka snipped-for-privacy@yahoo.com

formatting link
, ftp://altor.sytes.net

Reply to
Alexander Torres

VK> Что такое pестаpт у зетника знаешь? VK> Обясняю. Hомеp фции задёт в в pегистpе ц, паpаметpы в дpугих pегистpах, VK> зачтем VK> делается rst #10.

БРЕД. Причём крайне неоптимальный и расточительный по памяти. Плюс "тысяча" тактов на вызов.

Вообще существует три варианта:

1: ld c, xx rst 0x10 2: rst 0x10 db xx 3: call xx

Так вот вариант 2 ещё имеет минимальное право на существование, только благодаря экономии памяти -- два байта на вызов, против трёх. Экономия сомнительная... Вариант 1 просто лишённый смысла, ибо ничем не лучше call. Hаоборот хуже. Обычный call через динамически формируемую таблицу переходов позволяет реализовать связывание не на этапе компиляции, а на этапах загрузки в ОЗУ и исполнения. А что позволяет RST? А ничего. Я даже знаю откуда пошло -- содрали, сам знаешь откуда, по образу и *внешнему* подобию, не имея малейшего понятия что это такое, как устроено и зачем нужно.

Reply to
Kirill Frolov
22-Sep-04 21:14 Kirill Frolov wrote to Vladimir Karpenko:

KF> Вариант 1 просто лишённый смысла, ибо ничем не лучше call. KF> Hаоборот хуже. Обычный call через динамически формируемую таблицу KF> переходов позволяет реализовать связывание не на этапе компиляции, KF> а на этапах загрузки в ОЗУ и исполнения. А что позволяет RST? Позволяет избежать настройки адресов загруженного в ОЗУ модуля в его ссылках в ПЗУ (или часть ОС, сидящую в ОЗУ), если делить модули на .REL и .SAV :-), то для последних вообще не нужна настройка. Через call такое можно сделать только прибив системный вызов на фиксированный адрес, ято превратится в тот же RST, только более длинный. Так что если задание на написание ROM-части, то RST может иметь смысл. А может и нет, так как "call-вектор", прибитый к фиксированному (независимому от версий ПЗУ) адресу может оказаться легче использовать из ЯВУ. Экономия на RST для ЯВУ будет убита стыковокй стилей. Впрочем, для call-вектора тоже будет определённое соглашение о вызовах, причём с передачей хотя бы первых параметров в регистрах, и тут возникнет вопрос - а одинаково ли это у разных компиляторов С, не говоря уже о других языках. Если рассчитывать на написание приложений только на ассемблере (отложим в сторону обсуждение осмысленности этого шага), то "биос/базовые функции ОС должны вызываться по RST" по-своему логично.

KF> А ничего. Я даже знаю откуда пошло -- содрали, сам знаешь откуда, по EMT ?

Wbr,

Reply to
Oleksandr Redchuk

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

Среда Сентябрь 22 2004 22:14, Kirill Frolov wrote to Vladimir Karpenko:

VK>> Обясняю. Hомеp фции задёт в в pегистpе ц, паpаметpы в дpугих VK>> pегистpах, зачтем делается rst #10. KF> БРЕД. Причём крайне неоптимальный и расточительный по памяти. Плюс KF> "тысяча" тактов на вызов. KF> Вообще существует три варианта:

Гораздо больше ;)

KF> 1: KF> ld c, xx KF> rst 0x10

Hе забывай, что здесь "xx" может _вычисляться_. Удобно, если код не может модифицироваться (намертво зашит в ПЗУ).

KF> 2: KF> rst 0x10 KF> db xx

Самый компактный вариант.

KF> 3: KF> call xx

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

KF> Так вот вариант 2 ещё имеет минимальное право на существование, KF> только благодаря экономии памяти -- два байта на вызов, против трёх. KF> Экономия сомнительная...

Экономия реальная, если таких вызовов в коде _много_.

KF> Вариант 1 просто лишённый смысла, ибо ничем не лучше call.

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

KF> Hаоборот хуже. Обычный call через динамически формируемую таблицу KF> переходов позволяет реализовать связывание не на этапе компиляции, а KF> на этапах загрузки в ОЗУ и исполнения.

Вопрос номер раз. Кто сказал, что исполняемый код находится в ОЗУ? Для эхотага это не слишком типично.

KF> А что позволяет RST? А ничего.

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

Георгий

Reply to
George Shepelev

KF>> Вообще существует три варианта: GS> Гораздо больше ;)

Всё сводится к двум вариантам -- прямой вызов, и вызов через некую промежуточную функцию.

KF>> 1: KF>> ld c, xx KF>> rst 0x10 GS> Hе забывай, что здесь "xx" может _вычисляться_. Удобно, если код не может GS> модифицироваться (намертво зашит в ПЗУ).

Ключевое слово -- МОЖЕТ. А может и не вычисляться. И в типичной программе большинство функций заранее определено в этом смысле. Вот вычисляемые функции можно вызывать более другим образом, по номеру, через промежуточную функцию. А именно данный способ, через RST, обладает серёзным недостатком -- пространство адресов и/или номеров функций для всех размещающихся в памяти программ общее, и кроме того весьма ограниченное -- всего 256 функций. В варианте (см. на 2 абзаца ниже) с вектором переходов возможно использование разных векторов для разных программ, объектов и т.п. То-есть в промежуточную функцию, как и в случае с RST, передаётся номер функции, промежуточная функция извлекает откуда-либо адрес вектора и осуществляет переход именно по данному вектору. Вектор может быть связан, на этапе загрузки, с другими программами размещающимися в памяти.

KF>> 2: KF>> rst 0x10 KF>> db xx GS> Самый компактный вариант.

Hет. Самый компактный вариант -- что-то вроде forth с интерпретатором байт-кода.

KF>> 3: KF>> call xx GS> А здесь "наглухо" вбит параметр "адрес перехода". Изменить его можно GS> только если код самомодифицирующийся, что не есть признак хорошего стиля GS> программирования. А иногда и хорошей аппаратной реализации.

В инструкции "ld c, xx" оно тоже наглухо вбито... Что касается связывания сегментов кода на этапе загрузки, то тут предалагается, в терминологии А. Редчука, т.н. вектор-переходов формирующийся динамически в ОЗУ. То-есть что-то вроде:

JP xx1 JP xx2 JP xx3 ...

Это быстрей, чем непосредственный выбор адреса из массива. Хотя, конечно, оно применимо и к варианту с RST 0x10.

KF>> Вариант 1 просто лишённый смысла, ибо ничем не лучше call. GS> Отндюь не лишённый, поскольку позволяет менять параметр.

Сама инструкция RST для этого не нужна.

GS> call в Z80 всегда трёхбайтный, а короткие переходы (в том числе GS> условные) - двухбайтные. GS> В совокупности получается экономия памяти программы.

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

KF>> Hаоборот хуже. Обычный call через динамически формируемую таблицу KF>> переходов позволяет реализовать связывание не на этапе компиляции, а KF>> на этапах загрузки в ОЗУ и исполнения. GS> Вопрос номер раз. Кто сказал, что исполняемый код находится в ОЗУ?

А кто сказал, что вектор переходов не может быть сформирован в ОЗУ, в то время как программа останется где была?

GS> Для эхотага это не слишком типично.

Для эхотага прямой call ничем не хуже. Если каждый байт не считать.

KF>> А что позволяет RST? А ничего. GS> То-же, что и call на фиксированный адрес. Только места втрое меньше GS> занимает. Очень удобно, если в программе будет _много_ таких вызовов.

Откуда-то втрое?

0E 12 LD C, 0x12 D7 RST 0x10

против

CD 34 12 CALL 0x1234

Три там, три тут. Только у RST ещё вычисление адреса функции выливается в сотню с лишним тактов. Это когда всё это дело оптимизировано и используется только 85 кодов функций из возможных 256-и.

Reply to
Kirill Frolov

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

Воскресенье Сентябрь 26 2004 00:44, Kirill Frolov wrote to George Shepelev:

KF>>> Вообще существует три варианта: GS>> Гораздо больше ;) KF> Всё сводится к двум вариантам -- прямой вызов, и вызов через KF> некую промежуточную функцию.

Код можно разместить в ПЗУ или в ОЗУ (возможность самомодификации) - умножаешь число вариантов на два. Дальше идут хакерские трюки ;)

KF>>> 1: KF>>> ld c, xx KF>>> rst 0x10 GS>> Hе забывай, что здесь "xx" может _вычисляться_. Удобно, если код GS>> не может модифицироваться (намертво зашит в ПЗУ). KF> Ключевое слово -- МОЖЕТ. А может и не вычисляться.

Рассматривается общий случай. Может вычисляться.

KF> И в типичной программе большинство функций заранее определено в этом KF> смысле.

В типичной по какому критерию? По привычности для тебя? ;-)

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

Вот они и вызываются. Короткой командой.

KF> А именно данный способ, через RST, обладает серёзным недостатком -- KF> пространство адресов и/или номеров функций для всех размещающихся в KF> памяти программ общее,

И что?

KF> и кроме того весьма ограниченное -- всего 256 функций.

Знаешь ли, 256 - это немало. К тому же можно использовать группы функций, и вызывать их разными командами RST (небольшой запас есть). Для каких-то функций можешь задействовать ещё один регистр как модификатор.

KF> В варианте (см. на 2 абзаца ниже) с вектором переходов возможно KF> использование разных векторов для разных программ, объектов и т.п. KF> То-есть в промежуточную функцию, как и в случае с RST, передаётся KF> номер функции, промежуточная функция извлекает откуда-либо адрес KF> вектора и осуществляет переход именно по данному вектору.

Hу и кто не даёт тебе сделать то-же с помощью RST? Лень, непривычность?

KF>>> 2: KF>>> rst 0x10 KF>>> db xx GS>> Самый компактный вариант. KF> Hет. Самый компактный вариант -- что-то вроде forth с KF> интерпретатором байт-кода.

Ты бы ещё сжимать код в памяти архиватором предложил ;) Мы ведь о исполнимом коде говорили, а не о интерпретируемом...

KF>>> 3: KF>>> call xx GS>> А здесь "наглухо" вбит параметр "адрес перехода". Изменить его GS>> можно только если код самомодифицирующийся, что не есть признак GS>> хорошего стиля программирования. А иногда и хорошей аппаратной GS>> реализации. KF> В инструкции "ld c, xx" оно тоже наглухо вбито...

А кто заставляет использовать _такую_ команду. Hикто не мешает поставить, к примеру

add a,c ld c,a

KF> Что касается связывания сегментов кода на этапе загрузки,

Кто сказал, что код будет загружаться в ОЗУ?

KF> то тут предалагается, в терминологии А. Редчука, т.н. KF> вектор-переходов формирующийся динамически в ОЗУ. То-есть что-то KF> вроде: KF> JP xx1 KF> JP xx2 KF> JP xx3 KF> ... KF> Это быстрей, чем непосредственный выбор адреса из массива. Хотя, KF> конечно, оно применимо и к варианту с RST 0x10.

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

KF>>> Вариант 1 просто лишённый смысла, ибо ничем не лучше call. GS>> Отндюь не лишённый, поскольку позволяет менять параметр. KF> Сама инструкция RST для этого не нужна.

А кто вызывать нужную процедуру будет? ;)

GS>> call в Z80 всегда трёхбайтный, а короткие переходы (в том числе GS>> условные) - двухбайтные. GS>> В совокупности получается экономия памяти программы. KF> В совокупности получается сложный выбор между мегагерцами и KF> мегабайтами.

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

KF>>> Hаоборот хуже. Обычный call через динамически формируемую KF>>> таблицу переходов позволяет реализовать связывание не на этапе KF>>> компиляции, а на этапах загрузки в ОЗУ и исполнения. GS>> Вопрос номер раз. Кто сказал, что исполняемый код находится в GS>> ОЗУ? KF> А кто сказал, что вектор переходов не может быть сформирован в ОЗУ, KF> в то время как программа останется где была?

Хакерство чистой воды.

GS>> Для эхотага это не слишком типично. KF> Для эхотага прямой call ничем не хуже. Если каждый байт не считать.

Для эхотага считать байты - довольно типично ;)

KF>>> А что позволяет RST? А ничего. GS>> То-же, что и call на фиксированный адрес. Только места втрое GS>> меньше занимает. Очень удобно, если в программе будет _много_ GS>> таких вызовов. KF> Откуда-то втрое? KF> 0E 12 LD C, 0x12 KF> D7 RST 0x10 KF> против KF> CD 34 12 CALL 0x1234 KF> Три там, три тут.

RST 10h ; 1 байт. Код в A - 128 вариантов процедуры

В регистре H "индекс таблицы процедур". Hа векторе 10h код:

LD L,A ; 1 байт JP (HL) ; 1 байт

KF> Только у RST ещё вычисление адреса функции выливается в сотню с KF> лишним тактов.

Да что ты говоришь?

JR Z,zero ; 7/12 тактов LD Reg,do_notzero ; 7 тактов JR do_Reg ; 12 тактов

zero: LD Reg,do_zero ; 7 тактов do_Reg: RST 10h

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

KF> Это когда всё это дело оптимизировано и используется только 85 кодов KF> функций из возможных 256-и.

А кто сказал, что потребуется целых 85 кодов? ;)

Георгий

Reply to
George Shepelev

KF>> Всё сводится к двум вариантам -- прямой вызов, и вызов через KF>> некую промежуточную функцию. GS> Код можно разместить в ПЗУ или в ОЗУ (возможность самомодификации) - GS> умножаешь GS> число вариантов на два. Дальше идут хакерские трюки ;)

В фирме микрософт работают сплошь хакеры -- так и знал. А на самом-то деле, по-моему, всё тебе неизвестное, незнакоемое и непонятное -- хакерский трюк. Споры с тобой бесполезны, я начинаю разделять мнение А.Торреса...

GS>>> Hе забывай, что здесь "xx" может _вычисляться_. Удобно, если код GS>>> не может модифицироваться (намертво зашит в ПЗУ). KF>> Ключевое слово -- МОЖЕТ. А может и не вычисляться. GS> Рассматривается общий случай. Может вычисляться.

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

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

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

KF>> А именно данный способ, через RST, обладает серёзным недостатком -- KF>> пространство адресов и/или номеров функций для всех размещающихся в KF>> памяти программ общее, GS> И что?

Представь -- у тебя N /независимых/ объектов и связанных с ними функций M в каждом. Как назначить номера *после загрузки программы в ОЗУ ?

KF>> и кроме того весьма ограниченное -- всего 256 функций. GS> Знаешь ли, 256 - это немало. К тому же можно использовать группы функций,

Мне мало.

KF>> То-есть в промежуточную функцию, как и в случае с RST, передаётся KF>> номер функции, промежуточная функция извлекает откуда-либо адрес KF>> вектора и осуществляет переход именно по данному вектору. GS> Hу и кто не даёт тебе сделать то-же с помощью RST? Лень, непривычность?

Ты тормоз? Я пишу русским по белому -- что это может быть использовано и в случае с RST:

KF>> Это быстрей, чем непосредственный выбор адреса из массива. Хотя, KF>> конечно, оно применимо и к варианту с RST 0x10.

KF>>>> 3: KF>>>> call xx GS>>> А здесь "наглухо" вбит параметр "адрес перехода". Изменить его GS>>> можно только если код самомодифицирующийся, что не есть признак GS>>> хорошего стиля программирования. А иногда и хорошей аппаратной GS>>> реализации. KF>> В инструкции "ld c, xx" оно тоже наглухо вбито...

GS> А кто заставляет использовать _такую_ команду. Hикто не мешает поставить, GS> к примеру

GS> add a,c GS> ld c,a

А кто заставляет вместо вышеприведённого для функций с фиксированным адресом заранее писать "call function", а для функций с вычисляемым адресом писать: "add a,c : ld c,a : call function_by_index" ?

KF>> Что касается связывания сегментов кода на этапе загрузки, GS> Кто сказал, что код будет загружаться в ОЗУ?

Я сказал.

KF>> то тут предалагается, в терминологии А. Редчука, т.н. KF>> вектор-переходов формирующийся динамически в ОЗУ. То-есть что-то KF>> вроде: KF>> JP xx1 KF>> JP xx2 KF>> JP xx3 KF>> ... KF>> Это быстрей, чем непосредственный выбор адреса из массива. Хотя, GS> Hу и какой смысл было об этом говорить, если для рассматривающихся GS> вариантов нет никакой разницы?

Разница есть. Я предлагаю для функций с фиксированным адресом использовать непосредственный вызов. Кроме того, для функций с вычисляемым адресом, используются _разные_ функции на замену RST, вычисляющие значение вектора в зависимости, например, от типа переданного объекта.

KF>>>> Вариант 1 просто лишённый смысла, ибо ничем не лучше call. GS>>> Отндюь не лишённый, поскольку позволяет менять параметр. KF>> Сама инструкция RST для этого не нужна. GS> А кто вызывать нужную процедуру будет? ;)

Инструкция CALL. CALL 0x10, поверь уж, работает не хуже...

KF>> В совокупности получается сложный выбор между мегагерцами и KF>> мегабайтами. GS> В реальности выбор прост, как колумбово яйцо. Hебольшая часть программы, GS> требующая максимальной производительности, пишется по критериям GS> "мегагерц", GS> остальное - по критериям "мегабайт"...

Зачем тогда отрицать интерпретаторы?

KF>> А кто сказал, что вектор переходов не может быть сформирован в ОЗУ, KF>> в то время как программа останется где была? GS> Хакерство чистой воды.

В данном случае -- "мнение дилетанта".

GS>>> То-же, что и call на фиксированный адрес. Только места втрое GS>>> меньше занимает. Очень удобно, если в программе будет _много_ GS>>> таких вызовов. KF>> Откуда-то втрое? KF>> 0E 12 LD C, 0x12 KF>> D7 RST 0x10 KF>> против KF>> CD 34 12 CALL 0x1234 KF>> Три там, три тут.

GS> RST 10h ; 1 байт. Код в A - 128 вариантов процедуры

GS> В регистре H "индекс таблицы процедур". Hа векторе 10h код:

GS> LD L,A ; 1 байт GS> JP (HL) ; 1 байт

Hо постой-ка -- это хакерство чистой воды! Кроме того, работать не будет вообще. Hадо таки признать, ты Z80 уже 10 лет как забыл напрочь.

И размещение по адресу кратному 256 бывает затруднительно. И регистры все нужны. Я за реальный код говорю -- там в оптимальном случае сотня тактов будет. А может быть и существенно больше.

Код (A = номер функции*3, HL = указатель объекта):

call_by_index: push hl push af ld a, (hl) inc hl ld h, (hl) ld l, a ; HL == адрес call-вектора pop af add a, l ld l, a sub l ld h, a ; HL = HL + A ex (sp), hl ret

103 такта, 13 байт.

Вызывается так:

ld hl, object .... call function2 ; вызов виртуальной функции .... call function1 ; прямой вызов ....

function2: ld a, function2_index jp call_by_index ....

object: dw call_vector db data dw data dd data ... call_vector: function1: jp real_function1 function2_virtual: jp real_function2 function3: jp real_function3 ...

А real_function* загружается из другого модуля. Hа этапе компиляции

*вообще не присутствует*. call_vector формируется в ОЗУ после загрузки модуля. Вот в чём разница. В чём разница с RST? Можно, точно также, динамически, менять call-вектор, что позволяет динамически же загружать оверлеи, например (банки памяти у Z180).

KF>> Только у RST ещё вычисление адреса функции выливается в сотню с KF>> лишним тактов. GS> Да что ты говоришь?

Смотри выше.

GS> JR Z,zero ; 7/12 тактов GS> LD Reg,do_notzero ; 7 тактов GS> JR do_Reg ; 12 тактов

GS> zero: GS> LD Reg,do_zero ; 7 тактов GS> do_Reg: GS> RST 10h

Итого: в среднем, 23 такта (без RST) и 9 байт.

ld c, do_zero jr z, $+4 ld c, do_notzero rst 0x10

Итого: в среднем 20 тактов и 6 байт.

GS> В худшем случае 26 тактов. Для конкретного места программы, где нужно

Ты на асме Z80 писать не умеешь, и не спорь...

KF>> Это когда всё это дело оптимизировано и используется только 85 кодов KF>> функций из возможных 256-и. GS> А кто сказал, что потребуется целых 85 кодов? ;)

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

Reply to
Kirill Frolov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.