Info Guide
#05
30 апреля 2004 |
|
For Coderz - Маленькие программерские хитрости.
Этюды 1. Инкремент 32-разрядного числа Делается так: INC (HL),HL JR Z,$-2 ...и всё :) Причём, как видите, процедура универсальна - для 16/32/64/nn..-разрядных чисел - если переход через ноль гарантиро- ванно не происходит. (Именно в таком виде фрагмент удобен для подсчёта проходов не- коего куска программы.) Декремент при тех же условиях реализуе- тся сложнее: XOR A CP (HL) DEC (HL) INC HL JR NC,$-3 Или, если вероятен переход через ноль: SCF LD B,4 ;количество байт в числе LD A,(HL) SBC A,0 LD (HL),A INC HL DJNZ $-5 И инкремент для того же случая: SCF LD B,4 ;количество байт в числе LD A,0 ADC A,(HL) LD (HL),A INC HL DJNZ $-5 Ноль можно занести в C, если его нет в других регистрах. INC HL в частных случаях можно заменять на INC L или INC H. В регистрах же, как вы сами понимаете, обе операции выглядят ещё проще: инкремент: декремент: INC HL LD A,H LD A,H OR L OR L DEC HL JR NZ,$+3 JR NZ,$+3 INC DE DEC DE 2. Как избежать лишних INCBIN'ов Знаете, как можно в аласме подгрузить файл одним INCBIN'ом в два разных места? А то и больше? ;) Мне такое как раз требова- лось для Pro Tracker'а: плейер у меня на диске лежит целый, но в памяти он должен быть разрезан.А делается это с помощью ко- пирования памяти через фигурные скобки: ORG куда_копировать,стр_куда_откуда DISP откуда_копировать DUP длина/16 DW {$} DW {$} DW {$} DW {$} DW {$} DW {$} DW {$} DW {$} EDUP ENT Страница памяти "откуда_копировать" и страница "куда_копировать" должны быть од- ной и той же страницей "стр_куда_откуда". Я пробовал все варианты группировки DW: через DUP&REPEAT/UNTIL, через перечисление {$},{$+2} и т.д., пробовал менять $ на пе- ременную, но оказалось,что приведенный ва- риант самый быстрый. К тому же, он короче, чем {$},{$+2} ... :) Скорость на 3.5 MHz - около 1.5 кбайт/с. Для сравнения, скорость DS - около 8 кбайт/с. 3. Одно важное замечание Оказалось, способы выравнивания на гра- ницу параграфа (256 байт),которые я описы- вал в ZX-Guide, устарели. В новых аласмах допустима еще более короткая конструкция: DS .(-$) Вся её хитрость в том, что DS 0 ничего не делает :) Выравнивание на чётный байт в этом слу- чае записывается так: DS -$&1 А выравнивание на байт, кратный 8: DS -$&7 и т.п. А вот выравнивание на ближайший адрес, младший байт которого равен #F0: ORG $+15/256<8+#F0 или ORG $+15&#FF00+#F0 (в общем случае $+a&#FF00+b, где a=255-b ) 4. Контроль памяти при ассемблировании Вам никогда не приходилось делать в ис- ходнике контроль переполнения памяти для программы? Чтобы при превышении размера программы компиляция выводила на экран ка- кое-то сообщение? Обычно это делают через IF, в котором присутствует сравнение. А сравнение в синтаксисе аласма - это вычи- тание и проверка старшего бита. Но не ὀ, как можно было бы подумать, а... <1&1. Значительно короче :) Автор - Capry. Теперь, когда наше условие в IF выпол- нилось (проверить его работоспособность можно,искусственно удлинив программу каки- ми-нибудь DS'ами),нужно вывести сообщение. Это делает DISPLAY. А потом можно (но не обязательно) и прервать компиляцию - это сделает директива INCBIN с каким-нибудь диким названием файла. А. Кодер 08.03.04
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября