Inferno #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, в  котором  присутствует  сравнение. А 
сравнение  в синтаксисе аласма - это вычи-
тание  и  проверка  старшего  бита. Но  не
&#8000, как  можно было бы  подумать, а... 
<1&1. Значительно короче :) Автор - Capry. 
   Теперь, когда  наше условие в IF выпол-
нилось (проверить   его  работоспособность
можно,искусственно удлинив программу каки-
ми-нибудь DS'ами),нужно вывести сообщение.
Это  делает  DISPLAY. А потом можно (но не
обязательно) и  прервать  компиляцию - это
сделает  директива  INCBIN  с каким-нибудь
диким названием файла.

                         А. Кодер 08.03.04




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Мозаика - "Споры" об уставе ZXNet.
Еще одна планета железяка - схема музыкальной карточки Soundrive v. 1.05
Письмо - LENA'Stu о развитии Спектрума в Бобруйске.

В этот день...   19 ноября