Info Guide
#11
05 июля 2015 |
|
Системки - Оберон и ассемблер: Сопряжение с ассемблером (часть 2).
Оберон и ассемблер Сопряжение с ассемблером Передача параметров Передача параметров в регистрах в SDCC не реализована,хотя Филипп Краузе и обещал над этим подумать.Параметры функциям пере─ даются в стеке,верхним хранится адрес воз─ врата.Есть несколько способов получить па─ раметры, и вам необходимо выбрать наиболее приемлемый. Если параметр(ы) занимает(ют) 1 или 2 байта,то неплохим будет такой код: POP HL; Адрес возврата POP BC; Однобайтовый параметр ─ в C, PUSH BC; а если двухбайтовый, то в BC PUSH HL; Если в процедуре HL не ; портится, то можно заменить ; PUSH HL:RET на JP (HL) Или же так (такты и байты считайте сами): LD HL,#2 ADD HL,SP LD C,(HL); 1-й байт параметра(ов) INC HL LD B,(HL); 2-й байт параметра(ов) Если глубоко в теле подпрограммы требуется получение параметров в произвольном поряд─ ке, то, возможно, более оптимальным будет адресовать параметры черезIX: PUSH IX LD IX,#0 ADD IX,SP LD C,4(IX); 1-й байт параметра(ов) LD B,5(IX); 2-й байт параметра(ов) ... POP IX Функция не должна извлекать свои параметры из стека совсем, ─ в модели вызова по умо─ лчанию компилятор сам извлекает параметры после возвращения из функции (что в ряде случаев помогает ему оптимизировать код). Также функция не должна разрушать содержи─ мое регистраIX, через который SDCC рабо─ тает с локальными переменными. Результат функций в зависимости от раз─ мера возвращается в регистреL, в паре HL или вDE:HL. Эффективный вид Z80-кода, подходящий для портирования Коснёмся такого интересного вопроса, как портирование Спектрум-игр на другие плат─ формы. Не секрет, что код на ассемблере не слишком нагляден, но зато слишком объёмен. И для прояснения его логики часто приходи─ тся очень подробно разбирать огромные кус─ ки кода, пытаясь понять и описать, что они делают. Результаты такой кропотливой рабо─ ты не грех задокументировать, переписывая на более высокоуровневый язык, и здесь нам может помочь XDev, который предоставляет язык достаточно простой,чтобы быть развёр─ нутым на других платформах,но и достаточно современный концептуально, ибо,несмотря на свой почти 30-летний возраст,прекрасно ло─ жится практически на все современные аппа─ ратные и программные платформы,что я демо─ нстрировал примерами мидлетов наОбероне (http://zx.oberon2.ru/forum/ viewtopic.php?f=27&t=38 ) и даже некоторыми подвижками в разработке для Android (http://zx.oberon2.ru/forum/ viewtopic.php?f=87&t=244 ). А вот, например,Си, насколько мне из─ вестно, нельзя транслировать в байт-код Dalvik и в Java .class'ы, ибо Си имеет слишком много опасных возможностей, от ко─ торых в Java-машинах постарались избавить─ ся на уровне байт-кода. То же самое можно сказать о браузерных приложениях.Оберон же прекрасно ложится даже на микроконтрол─ леры (http://www.youtube.com/ watch?v=zlnjбFCY1tY ), не говоря уж оJVM и .NET (http://gpcp.codeplex.com ). К сожалению,формат журнальной статьи не позволяет развёрнуто описать процессы миг─ рации Z80-кода на другие платформы,но если вам интересно, как могут выглядеть интер─ фейсы библиотек и прикладной код, трансли─ руемый в различные (очень различные!) тар─ геты, то смотрите среду XDev (и её подсис─ темы для разработки под разные платформы) и среду Monkey X(http://monkey-x.ru), ко─ торая также предлагает трансляцию с едино─ го языка под различные таргеты, что при всех недостатках реализации (ей далеко до универсальности, но всё нужно развивать) экономит время и ресурсы, которые в проти─ вном случае тратились бы на изучение деся─ тков (быстроменяющихся) языков, платформ и их API. Ещё хотелось бы отметить,что я не видел ни одного удовлетворительного решения для одномоментной разработки для Спека и дру─ гих платформ. Вы можете возразить, что ни─ кого не интересует скрещивание Спека с ПЦ. Я же могу возразить в ответ ─ а почему одинаковая программа или игра должна быть написана по-разному для разных платформ? И особенно на разных языках, которых сейчас как собак нерезаных.Устаю удивляться,когда просто читаю новые названия языков. Не кроется ли здесь проблема, которой вы не заметили? Так почему же я не считаюСи таким хо─ рошим средством для одномоментной разрабо─ тки. Во-первых, см. выше о том, какСи ло─ жится на современные платформы, а, вернее, уже не ложится. Во-вторых, посмотрите не─ предвзятым взглядом на исходники любой иг─ рушки для Спектрума, написанной наСи[ну, не считая игр на движке Churrera -Ред.]. Вы не обращали ранее внимания на обилие вставок на асме? Так вот,я вас уверяю: это приговор. Хотя и приятно, что не целиком всё на асме.Вобщем,не видел ни одного сре─ дства разработки, при помощи которого уда─ лось бы хотя бы частично автоматизировать процесс вытаскивания игры из рамок спект─ румных ограничений. Нужно всё переписывать заново. XDev тоже не является таким средс─ твом,ноОберон как язык при всей жёсткости его каркаса и обилии ограничений ─ в об─ щем-то хорошая основа для мультитаргетной разработки, как мне кажется. Но предстоит изучение его возможностей в этом плане и, разумеется,их совершенствование. Важно по─ нимать, что я не предлагаю панацею, просто обозначаю проблему и призываю искать пути её решения, если вам это интересно. Мы мигрируем от Z80-асма кСи, но, не найдя в нём достаточной опоры для приклад─ ного высокоуровневого программирования ─ безопасного, наглядного средства для прог─ рамм со сложной структурой и мета-програм─ мирования (скриптования) (http://forum.oberoncore.ru/ viewtopic.php?f=6&t=5267 ), оставаясь в рамках компилируемого кода, мы движемся дальше,к Оберону, но оставляем за собой возможность юзать для низкого уровня и асм, иСи, и Java, если понадобится (по─ следнее не для ZX,конечно,а для Java-based платформ). Вот поэтому я вижу языкСи в применении к другим платформам в роли асма Z80 для Спека. Хорошо для низкого уровня, но начинает нервировать, когда идёт работа со сложной прикладной логикой. С учётом того, что к коду на Z80 хорошо бы приложить удобный и однозначно соответ─ ствующий логике асмовского код на языке высокого уровня, а главное ─ компилируемый и исполняемый (а в идеале ─ ещё и кросс─ платформенный!), оставляя за бортом упоми─ нание о множестве проблем совместимости и различий по библиотекам, интерфейсам и ещё много чего, просто покажу, как может выг─ лядеть код,реализующий игру для Спектрума/ Z80 и других платформ одномоментно, вовсе не утверждая, кстати, что XDev ─ идеальная среда для этих применений (в этот момент асмеры кричат "маздай" и бьются в парокси─ змах ЯВУ-ненавистничества в применении к Спектруму). Итак,вот процедура опроса клавиатуры из игры "Дурак" от CopperFeet, портированная наОберон с Laser Basic'а, а потом допол─ ненная альтернативной реализацией на ассе─ мблере: MODULE Durak; IMPORT M := Asm, B := Basic, Cfg; TYPE KeyCode = CHAR; VAR time: INTEGER; (* Scan keys & return a control code: *) PROCEDURE GetKey (): KeyCode; BEGIN IF Cfg.Oberon THEN (* ~ 2 min 50 sec to play music: *) DEC(time, 9); B.PAUSE(9); (* <Y>, <U>, <I>, <O>, <P>: *) IF BITS(B.PORTIN(ODFFEH))*BITS(1FH) # BITS(1FH) THEN RETURN 2X END; (* <Q>, <W>, <E>, <R>, <T>: *) IF BITS(B.PORTIN(OFBFEH))*BITS(1FH) # BITS(1FH) THEN RETURN 1X END; (* <A>, <S>, <D>, <F>, <G>: *) IF BITS(B.PORTIN(OFDFEH))*BITS(1FH) # BITS(1FH) THEN RETURN 3X END; (* <H>, <J>, <K>, <L>, <Enter>: *) IF BITS(B.PORTIN(OBFFEH))*BITS(1FH) # BITS(1FH) THEN RETURN 4X END; (* <B>, <N>, <M>, <SS>, <Space>: *) IF BITS(B.PORTIN( 7FFEH))*BITS(1FH) # BITS(1FH) THEN RETURN 5X END; ELSE (* DEC(time, 9): *) M.Code("LD HL, (_Durak_time) "); M.Code("LD DE, #0-9 "); M.Code("ADD HL, DE "); M.Code("LD (_Durak_time), HL "); (* B.PAUSE(9): *) M.Code("LD HL, #9 "); M.Code("PUSH HL "); M.Code("CALL _Basic_PAUSE_DI_stdcall"); (* <Y>, <U>, <I>, <O>, <P>: *) M.Code("LD BC, #OxDFFE "); M.Code("IN A, (C) "); M.Code("CPL "); M.Code("AND #0x1F "); M.Code("LD L, #2 "); M.Code("RET Z "); (* <Q>, <W>, <E>, <R>, <T>: *) M.Code("DEC L "); M.Code("LD BC, #OxFBFE "); M.Code("IN A, (C) "); M.Code("CPL "); M.Code("AND #0x1F "); M.Code("RET Z "); (* <A>, <S>, <D>, <F>, <G>: *) M.Code("LD BC,#OxFDFE "); M.Code("IN A, (C) "); M.Code("CPL "); M.Code("AND #0x1F "); M.Code("LD L, #3 "); M.Code("RET Z "); (* <H>, <J>, <K>, <L>, <Enter>: *) M.Code("INC L "); M.Code("LD BC, #OxBFFE "); M.Code("IN A, (C) "); M.Code("CPL "); M.Code("AND #0x1F "); M.Code("RET Z "); (* <B>, <N>, <M>, <SS>, <Space>: *) M.Code("INC L "); M.Code("LD BC, #0x7FFE "); M.Code("IN A, (C) "); M.Code("CPL "); M.Code("AND #0x1F "); M.Code("RET Z "); END; RETURN 0X END GetKey; END Durak. Что любопытно, асмовский код, конечно, компактнее,но если сжать это дело Hrum'ом, то в результате сжатая обероновская реали─ зация по размеру меньше, чем сжатая асмов─ ская. Что позволяет сделать смелый вывод: при достаточном количестве памяти и быст─ родействии в случае загрузки машинного ко─ да в уже сжатом виде (и при разумной ско─ рости распаковки) остаётся экономить лишь адресное пространство,которое в таком слу─ чае и является основным ресурсом для эко─ номии и самым весомым аргументом за асм- реализацию в случае его недостаточности, тогда как для некоторых проблем важнее иметь не столько экономию адресного прост─ ранства, сколько бОльшую простоту и гиб─ кость разработки (макетирование,прототипи─ рование, средства отладки и т.д.). [Впро─ чем,мы можем использовать интерпретируемый пи-код для экономии адресного пространст─ ва, потеряв при этом в скорости -Ред.] Возможности Оберон-языков, отсутствующие в ZXDev Есть ряд возможностейОберона, которые вряд ли будут когда-либо реализованы для разработки под процессор Z80. Это динами─ ческая модульность (загрузка-выгрузка мо─ дулей "на лету"),автоматическое управление памятью (сборка мусора; но пользоваться динамической памятью всё-таки можно, явно освобождая её с помощьюPlatform.DISPOSE), возможности ядра по мета-программированию, обработке исключений, моментальной (по─ смертной) отладке и т.д. Как вы понимаете, скорости и памяти (особенно адресного про─ странства) Z80 явно недостаточно, чтобы в полной мере почувствовать прелесть разра─ ботки на Оберон-языках.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября