Как стартовать первую программу на ассемблере.
По небольшим просьбам публикую самую короткую и простую инструкцию, как с минимальными усилиями написать и запустить примитивную программу на ассемблере. Я нарочно не затрагиваю тут принципов работы, литературу, архитектуру итд. Цель — получить нечто двигающееся здесь и сейчас.
Нужно всего ничего:
1. Кросс-ассемблер.
2. Эмулятор.
3. Блокнот.
Кроссассемблер можно взять SjASMPlus.
sourceforge.net/projects/sjasmplus/ — улучшенная версия от Aprisobal. Скачиваем и кладем sjasmplus.exe в папку с проектом, остальные файлы из архива напрямую не пригодятся.
В качестве эмулятора рекомендую взять Unreal Speccy.
github.com/tslabs/zx-evo/raw/master/pentevo/unreal/Unreal/bin/unreal.7z — версия от TS-Labs. Распаковываем его в подпапку unreal в папке проекта.
Блокнот сойдет стандартный из windows. Запускаем блокнот, создаём файл cooldemo.asm, пишем туда вот такую программу:
Запускаем блокнот, создаём compile.bat, который упростит нам постоянную компиляцию. Его содержимое просто:
Первая строка запускает компиляцию вышеописанного файла, после чего создается снапшот (см. выше SAVESNA директиву).
Третья строка сразу запускает эмулятор, чтобы посмотреть описанное.
Запускаем compile.bat — если всё получилось, то запустится эмулятор со страшно тормозным разноцветным нечто. Поздравляю, теперь ты — демосценер, и оправданий чтоб не писать демы больше не осталось :)
Нужно всего ничего:
1. Кросс-ассемблер.
2. Эмулятор.
3. Блокнот.
Кроссассемблер можно взять SjASMPlus.
sourceforge.net/projects/sjasmplus/ — улучшенная версия от Aprisobal. Скачиваем и кладем sjasmplus.exe в папку с проектом, остальные файлы из архива напрямую не пригодятся.
В качестве эмулятора рекомендую взять Unreal Speccy.
github.com/tslabs/zx-evo/raw/master/pentevo/unreal/Unreal/bin/unreal.7z — версия от TS-Labs. Распаковываем его в подпапку unreal в папке проекта.
Блокнот сойдет стандартный из windows. Запускаем блокнот, создаём файл cooldemo.asm, пишем туда вот такую программу:
DEVICE ZXSPECTRUM128 ;это внутренняя директива SJASMPLUS, которая подсказывает ему, под какой клон организовать память
ORG #8000 ;старт программы ровно по центру памяти 48К
START
DI ;запрет прерываний на всякий случай
LD A,255 ;кладем в регистр A значение 255 (просто наугад)
LOOP0
LD HL,#4000;задаём адрес начала экрана в регистр HL, будем туда писать всякие байты
LD B,192+24;в регистр B кладем высоту экрана в байтах, плюс еще 24 байта, чтобы кроме точек красились еще и аттрибуты
LOOP1
LD C,32 ;в регистр C кладем ширину экрана в байтах
LOOP2
LD (HL),A ;кладем по адресу, заданному регистром HL значение регистра A
INC HL ;увеличиваем на единицу адрес экрана
DEC A ;уменьшаем на единицу значение в регистре A, просто чтобы всё время что-то новое выводить
DEC C ;уменьшаем счетчик ширины на единицу
JP NZ,LOOP2;пока C не достигло нуля, прыгаем на LOOP2, иначе идем дальше
DEC B ;
JP NZ,LOOP1;пока B не достигло нуля, прыгаем на LOOP1, иначе идем дальше
DEC A ;на единичку уменьшим A, чтобы следующий кадр отрисовывать с чего-то другого
JP LOOP0 ;зарисовали весь экран ерундой, начнем сначала, но уже с тем A, какой попадется
SAVESNA "unreal/cooldemo.sna",START ;в папку unreal после компиляции сохранится снапшот для запуска в эмуляторе, содержащий программу, описанную сверху
Запускаем блокнот, создаём compile.bat, который упростит нам постоянную компиляцию. Его содержимое просто:
sjasmplus.exe cooldemo.asm
pause
unreal\Unreal.exe unreal\cooldemo.sna
Первая строка запускает компиляцию вышеописанного файла, после чего создается снапшот (см. выше SAVESNA директиву).
Третья строка сразу запускает эмулятор, чтобы посмотреть описанное.
Запускаем compile.bat — если всё получилось, то запустится эмулятор со страшно тормозным разноцветным нечто. Поздравляю, теперь ты — демосценер, и оправданий чтоб не писать демы больше не осталось :)
71 комментарий
Да… не написано как именно запускать блокнот.
Гит репозиторий для такого мелкого исходника конечно сильно избыточно, а вот если серия статей, то…
Примерно вот так это может выглядеть:
https://gitlab.com/processing-projects/Enhanced-Wild-demo.git
1. если человек не в состоянии осилить бат и при этом не в состоянии задать вразумительный вопрос самому себе (что такое бат и по какой причине не работает) и вбить этот вопрос в гугл или спросить в статье (напоминаю — вразумительно) — в асм дальше лезть бессмысленно. по себе знаю — я либо не вылезаю из гугла, либо если не могу сформулировать или не нахожу ответ — пытаю тех, кто в этом разбирается, в личках). мне как правило стыдно задавать «нубские» вопросы в открытую.
ну или поступать так
2. опускаемся до уровня детского сада и начинаем: итак, дети, вот это файлик. в файлике есть разные слова, каждое слово делает что-то свое. и далее по тексту
Привычку гуглить всё подряд необходимо прививать. Многим и в голову не приходит поискать, либо они не представляют, что и как искать. Вот даже авторам статей как-то не приходит в голову поискать и вставить ссылку на более глубокое раскрытие побочной темы, а казалось бы, дело пары минут.
Касательно веры. Полным-полно отличных программистов на ассемблере, которые вообще не переваривают и не понимают куда как более простой и очевидный Си, или другие ЯВУ. С трудом верится, что человек, который пишет сложный код на ассемблере, не может написать себе элементарную утилиту на ЯВУ, но это — факт, встречается постоянно. И среди новичков, и среди тех, кто пишет код десятилетиями.
А вообще вся эта тема, когда подсказываешь из практического опыта, как можно сделать лучше, а тебе упорно начинают доказывать, что этого делать не надо, отбивает желание как-то реагировать в будущем.
не переварил от слова совсем.
по остальному: за себя могу сказать, что для меня нет разницы какой язык (они все одинаковы) — важно место примения (архитектура, апи, встроенные методы)
Ну раз не переварил, остаётся умыть руки и не тратить время попусту.
а мыть руки полезно, желательно по нескольку раз в день — одобряю.
ЗЫ да, ме чего-то захотелось поговорить.
Ну и будем честны, пример Дениса Грачёва с его любимым ЭМУЗИНОМ вполне наглядно это демонстрирует :)
так я и не спорю, только это, на мой скромный взгляд, скорее исключение. но бат (коммандная строка вообще) это же азы винды — не все же крысой делается. правда иногда нужен пинок в нужном направлении, что бы ВСЕ и сразу СТАЛО ПОНЯТНЫМ — с этим даже на секунду спорить не буду. правда это опятьже, скорее всего, редкое исключение
Ребят, я вижу что у людей какой-то подъём и хочется многим стартануть в увлекательный и интересный мир программирования на z80. Что вас РЕАЛЬНО тормозит? Возможно вы больше практики, как я, и нужна куча мелких практических примеров (графика, спрайты, музыка, математика и.т.п) или же нужна скучная и нудная теория про хексы и пальцы процессора с регистрами? Дело в том что я до сих пор считаю себя новичком, поэтому могу по простому рассказать что знаю :)
1) Как разбить код на модули? Т.е., я понимаю, что там есть какая-то система подпрограмм, но я не допер, как с этим работать.
2) Как хранить и работать с кусками кода, например, массивы. Это вообще возможно?) Я понимаю, что из «переменных» у нас только регистры, но должен же быть «precalculated» способ.
Это что навскидку тормозит
include "..." — инклудит другой файл асм
в бинарниках у тебя может быть картинка, музыка, что-то еще (прекалк)
ну а в амсах могут быть отдельные процедуры, которые не стоит копировать из проекта в проект, а проще приинклудить из какой-то общей папки
Артем, смотри — объясню как умею и понимаю:
когда процессор встречает команду call <адрес>, то он бросает на стек содержимое регистра PC+3, меняет значение PC на <адрес> и продолжает выполнение. т.е. следующая команда будет браться уже из <адрес>. а когда встречается команда ret, то берется значение с вершины стека и пихается в PC, потом опять же идет продолжение выполнения программы.
командами push/pop ты сохраняешь/восстанавливаешь значения регистров в стек/ из стека. и соответственно косвенно изменяешь значение регистра SP (указатель на вершину стека). и если ты запихал в стек допустим 2 регистра, а восстановил 1, то при выполнении команды ret со стека возьмется что? правильно — хрень! и выполнение программы начнеться по направлению неведомой черной дыры :)
вот как-то так
но на всякий случай — первый пришел, последний ушел.
допустим мы стек бросаем значения
1, 2, 3, 4.
на вершине стека у нас значение 4.
что бы достать значение 1, то надо стек разобрать в обратном порядке — достаем 4,3,2,1
в таком случае обратиться к меткам модуля можно через префикс mydemo, например CALL mydemo.somemethod
2) Для массивов удобнее всего использовать индексные регистры ix,iy. С их помощью можно обращаться к элементам в диапазоне +-128 байтов. Ну и смотря что ты с массивом хочешь сделать. Например я в игрухах делаю примерно так:
При вызове doEnemies каждый враг из списка сдвинется вниз на 1 и его энергия уменьшиться на 1 :)
Устраняем одно препятствие — один процент потенциальных кодеров конвертируется в 0.01 человека. Устраняем еще 100 препятствий — получаем демосценера. Всё просто. Сможем ли мы устранить 100 препятствий? хз, я просто решил очень конкретную и простую задачу в этом посте.
Bat-ы вполне себе встречаются, я уже не говорю про *nix-пользователей, где половина вещей (как минимум) делается в терминале. Опять же, по поводу IDE, это смотря какой ещё. Пока какой-нибудь Eclipse настроишь, ещё и не такое гуглить придётся :)
По удобству не знаю, я сделал 10 игр и сколько-то там демок. Никакого дискомфорта!
Берется Pasmo, пишется:
сборка: