Как стартовать первую программу на ассемблере.

По небольшим просьбам публикую самую короткую и простую инструкцию, как с минимальными усилиями написать и запустить примитивную программу на ассемблере. Я нарочно не затрагиваю тут принципов работы, литературу, архитектуру итд. Цель — получить нечто двигающееся здесь и сейчас.



Нужно всего ничего:
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 комментарий

avatar
Спасибо тебе, moroz1999!
avatar
Офигенно, спасибо)
avatar
Чорт! Последнюю отмазку отобрал! :-)
  • nyuk
  • +4
avatar
в регистр B кладем ширину экрана в байтах
исправь на C
avatar
Спасибо!
avatar
Спасибо, запустилось! :-)
avatar
нет слов )
avatar
moroz1999 материал хороший но не хватает скриншотов эффекта, а лучше процесс набора исходника и его компиляции записать в ютуб. Исходники вместе с откомпилированным бинарником и настроенным эмулятором надо опубликовать на github.
Да… не написано как именно запускать блокнот.
  • Nuts_
  • -4
avatar
Я понял сарказм, спасибо. В следующий раз человеку, которому понадобился совет с самым первым шагом, я тупо скину в личку, вместо статьи.
avatar
Нет, не понял :(
avatar
Извиняюсь, если не так понял и перереагировал.
avatar
Кстати, соглашусь с Nuts_ , видео туторы заходят быстрее и показывают не столько процесс, сколько простоту.
Гит репозиторий для такого мелкого исходника конечно сильно избыточно, а вот если серия статей, то…

Примерно вот так это может выглядеть:



https://gitlab.com/processing-projects/Enhanced-Wild-demo.git
avatar
Про блокнот на самом деле смешно, но серьёзно. Сейчас уже такое время, когда куча людей, каких-никаких PC-шных программистов, впадает в ступор, когда речь заходит про bat-файлы и блокнот. Они же привыкли работать в IDE, а тут по двойному клику ничего само не открывается и ничего не понятно. И как ни странно, если помочь им это препятствие преодолеть, у них что-то потом получается, хотя казалось бы, не осилил batch, куда тебе ассемблер. Просто дополнительный психологический барьер.
avatar
А ещё гвоздь программы — постоянно задаваемый в контексте таких примеров вопрос 'я скачал и запустил программу, но она открывается и сразу закрывается, что делать, она не работает?' (про ассемблеры и прочие утилиты). И когда человек слышит про командную строку и bat-файлы, вообще теряется.
avatar
тех, кто пугается «черного окошка» и не в состоянии дописать слово pause стрелять на месте без суда и туда
avatar
Стрелять — это неконструктивно. Можно тогда чуть-чуть поднять планку и сказать — тех, кто не в состоянии сам написать то, что описано в посте, стрелять без суда. Только элита, только хардкор. Но все, включая элиту, когда-то делали что-то впервые и не понимали. Конструктивнее анализировать ситуацию, ловить проблемные места и предупреждать вопросы по ним в статье.
avatar
соглашусь, но с небольшим (или большим) НО
1. если человек не в состоянии осилить бат и при этом не в состоянии задать вразумительный вопрос самому себе (что такое бат и по какой причине не работает) и вбить этот вопрос в гугл или спросить в статье (напоминаю — вразумительно) — в асм дальше лезть бессмысленно. по себе знаю — я либо не вылезаю из гугла, либо если не могу сформулировать или не нахожу ответ — пытаю тех, кто в этом разбирается, в личках). мне как правило стыдно задавать «нубские» вопросы в открытую.
ну или поступать так
2. опускаемся до уровня детского сада и начинаем: итак, дети, вот это файлик. в файлике есть разные слова, каждое слово делает что-то свое. и далее по тексту
avatar
Согласен с ShaMAN. С трудом верится, что человек, который не осиливает bat, сможет что-то сделать в ассемблере.
avatar
Практика показывает, что некоторые (разумеется не все) могут. Просто batch и командная строка — это лишние и неожиданные сущности, которые уже не встречаются повсеместно, не на слуху, но внезапно возникают в самом начале пути.

Привычку гуглить всё подряд необходимо прививать. Многим и в голову не приходит поискать, либо они не представляют, что и как искать. Вот даже авторам статей как-то не приходит в голову поискать и вставить ссылку на более глубокое раскрытие побочной темы, а казалось бы, дело пары минут.

Касательно веры. Полным-полно отличных программистов на ассемблере, которые вообще не переваривают и не понимают куда как более простой и очевидный Си, или другие ЯВУ. С трудом верится, что человек, который пишет сложный код на ассемблере, не может написать себе элементарную утилиту на ЯВУ, но это — факт, встречается постоянно. И среди новичков, и среди тех, кто пишет код десятилетиями.

А вообще вся эта тема, когда подсказываешь из практического опыта, как можно сделать лучше, а тебе упорно начинают доказывать, что этого делать не надо, отбивает желание как-то реагировать в будущем.
avatar
вот это
А вообще вся эта тема, когда подсказываешь из практического опыта, как можно сделать лучше, а тебе упорно начинают доказывать, что этого делать не надо, отбивает желание как-то реагировать в будущем.
не переварил от слова совсем.
по остальному: за себя могу сказать, что для меня нет разницы какой язык (они все одинаковы) — важно место примения (архитектура, апи, встроенные методы)
avatar
Ты — не центр мира. Мы обсуждаем не тебя.

Ну раз не переварил, остаётся умыть руки и не тратить время попусту.
avatar
а кто сказал, что центр? я просто привожу пример. я далеко не гуру, просто кмею мыслить и анализировать. я вообще обладатель одной офигительной специализации в области программирования (рчень многих тошнит) — я адинэснег.

а мыть руки полезно, желательно по нескольку раз в день — одобряю.

ЗЫ да, ме чего-то захотелось поговорить.
avatar
чего-то я нарчепятывался)
avatar
Парадоксально, я в приватном разговоре повторил на днях +- один-в-один аргумент шамана. Но вот то, что ты сказал, лично меня переубеждает. Наверное, нужно просто меньше думать за других, а просто поддерживать разные стратегии работы.
avatar
а можно подробнее? если это возможно
avatar
Ну вот я тоже верил, что если человек боится блокнота, наверное, не нужно тратить время объясняя. Но Shiru показывает, что м.б. это ложный выбор, м.б. если пойти навстречу такому пользователю, что-то хорошее всё же может из этого выйти.

Ну и будем честны, пример Дениса Грачёва с его любимым ЭМУЗИНОМ вполне наглядно это демонстрирует :)
avatar
:)
так я и не спорю, только это, на мой скромный взгляд, скорее исключение. но бат (коммандная строка вообще) это же азы винды — не все же крысой делается. правда иногда нужен пинок в нужном направлении, что бы ВСЕ и сразу СТАЛО ПОНЯТНЫМ — с этим даже на секунду спорить не буду. правда это опятьже, скорее всего, редкое исключение
avatar
У меня есть знакомые, гуру баша и шелл-скриптов. Батников пугаются, так что =)
avatar
даладно???!!! :D
avatar
Моя прелесть, мой Эмузвин!

Ребят, я вижу что у людей какой-то подъём и хочется многим стартануть в увлекательный и интересный мир программирования на z80. Что вас РЕАЛЬНО тормозит? Возможно вы больше практики, как я, и нужна куча мелких практических примеров (графика, спрайты, музыка, математика и.т.п) или же нужна скучная и нудная теория про хексы и пальцы процессора с регистрами? Дело в том что я до сих пор считаю себя новичком, поэтому могу по простому рассказать что знаю :)
avatar
Меня тормозит сейчас вот такой список насущных вопросов:
1) Как разбить код на модули? Т.е., я понимаю, что там есть какая-то система подпрограмм, но я не допер, как с этим работать.
2) Как хранить и работать с кусками кода, например, массивы. Это вообще возможно?) Я понимаю, что из «переменных» у нас только регистры, но должен же быть «precalculated» способ.

Это что навскидку тормозит
avatar
incbin "..." — инклудит бинарные данные
include "..." — инклудит другой файл асм

в бинарниках у тебя может быть картинка, музыка, что-то еще (прекалк)
ну а в амсах могут быть отдельные процедуры, которые не стоит копировать из проекта в проект, а проще приинклудить из какой-то общей папки
avatar
асмах*
avatar
Ок, спасибо. Какой аналог в асме GOSUB/RETURN?) Я так понял, там какая-то работа со стеком, но не очень допер, что и как реально работает.
avatar
Ну вот синтетический пример реализации GOSUB/RETURN. Ничего полезного не делает, но принцип вроде понятен.


	ld a, #01
	call SUB	; вызываем процедуру SUB с параметром #01
	halt
	ld a, #fe
	call SUB	; еще раз вызываем процедуру SUB с параметром #FE

	di : halt	; стоп машина

; Собственно процедурура SUB
; A - параметр, с которым она играется
SUB
	ld b, a
	xor a	; наигрались :-)
	ret	; возвращаемся туда, откуда пришли
avatar
(SUB нельзя использовать в качестве имени метки)
avatar
только надо добавить, что в начале процедуры надо push все регистры которые портишь, а перед выхором pop их обратно
avatar
Ну это не абсолют же. Можно хоронить регистры в самой процедуре. Можно вообще забить. По-всякому оно бывает.
avatar
я вот для этого написал
Я так понял, там какая-то работа со стеком, но не очень допер, что и как реально работает.

Артем, смотри — объясню как умею и понимаю:
когда процессор встречает команду call <адрес>, то он бросает на стек содержимое регистра PC+3, меняет значение PC на <адрес> и продолжает выполнение. т.е. следующая команда будет браться уже из <адрес>. а когда встречается команда ret, то берется значение с вершины стека и пихается в PC, потом опять же идет продолжение выполнения программы.
командами push/pop ты сохраняешь/восстанавливаешь значения регистров в стек/ из стека. и соответственно косвенно изменяешь значение регистра SP (указатель на вершину стека). и если ты запихал в стек допустим 2 регистра, а восстановил 1, то при выполнении команды ret со стека возьмется что? правильно — хрень! и выполнение программы начнеться по направлению неведомой черной дыры :)
вот как-то так
avatar
принцип работы стека знаешь? надеюсь, что знаешь)
но на всякий случай — первый пришел, последний ушел.
допустим мы стек бросаем значения
1, 2, 3, 4.
на вершине стека у нас значение 4.
что бы достать значение 1, то надо стек разобрать в обратном порядке — достаем 4,3,2,1
avatar
Да, знаю, конечно)
avatar
примечание: на стек идут только регистровые пары и данные по 2 байта
avatar
В принципе, очевидная тонкость для меня, но возможно кому-то будет полезно. Спасибо!
avatar
Йей! Спасибо!
avatar
вот мне как-то Нючек пример накидал yadi.sk/d/xn5k9AYxv9GYB
avatar
Местами ужос конечно. Особенно разборка-сборка PCX впечатлила. Автор тогда еще не знал, что можно просто вот так:
incbin "res/Sosochi.pcx", 128
avatar
оу! типа не с первого байта, а со стодвадцатьвосьмого? круто, чо)
avatar
Подстраховаться и экранировать область видимости меток можно через директивы MODULE/ENDMODULE.

            MODULE mydemo
somemethod
            ;some code here
            RET
            ENDMODULE


в таком случае обратиться к меткам модуля можно через префикс mydemo, например CALL mydemo.somemethod
avatar
Блин, всё так просто :D
avatar
1) Если модуль это просто набор подпрограмм то пишешь их в отдельный файл и include
2) Для массивов удобнее всего использовать индексные регистры ix,iy. С их помощью можно обращаться к элементам в диапазоне +-128 байтов. Ну и смотря что ты с массивом хочешь сделать. Например я в игрухах делаю примерно так:

При вызове doEnemies каждый враг из списка сдвинется вниз на 1 и его энергия уменьшиться на 1 :)


enemiesList
;один враг - 3 байта
;0,1 байты координаты y,x
;2 энергия
;описываем 4 врага
    defb 04,07,64
    defb 14,21,64
    defb 06,11,64
    defb 06,04,64

    defb 255; 255 - конец списка врагов

doEnemies

    ;указатель на начало списка врагов
    ld ix,enemiesList

    ;размер структуры
    ld bc,3

        doOneEnemy

        ;проверяем не дошли ли мы до конца списка
        ld a,(ix+4);один враг 3 байта
        cp 255; сравниваем с 255
        ret z ;возвращаемся если 255

        ;сдвигаем каждого врага по y на единичку

        ld a,(ix);нулевой байт - у координата
        dec a ;уменьшаем на 1
        ld (ix),a ;сохраняем

        ;и уменьшаем энергию на 1
        ld a,(ix+2)
        dec a ;уменьшаем на 1
        ld (ix+2),a ;сохраняем

        add ix,bc ;сдвигаем указатель на размер структуры

        jr doOneEnemy ;переходим к следующему врагу

avatar
Label + defb — это, я так понимаю, и есть массив. О как! УДобно, спассибо!
avatar
Да, это даже не массив и список структур :) Только у меня последний враг не обработается, ну не суть :)
avatar
Абсолютно соглашусь с каждым словом. У одних людей — одни препятствия, у других — другие. Кому-то сложно начать, кому-то непонятно, как искать, кому-то непонятно, у кого спросить.
Устраняем одно препятствие — один процент потенциальных кодеров конвертируется в 0.01 человека. Устраняем еще 100 препятствий — получаем демосценера. Всё просто. Сможем ли мы устранить 100 препятствий? хз, я просто решил очень конкретную и простую задачу в этом посте.
avatar
кто бы еще эту иде написал. можно конечно пользовать и описывать саблим/нп++, но и там, вот бида, надо батники писать
avatar
а проще — поделиться своим способом и своими наработками — для быстрого старта
avatar
идея есть, но я никак не соберусь с мыслями и не могу поймать музу — еще по весне запланирован цикл статей по поребрику. я помню, что минимум двум человекам эта тема интересна. там как раз по второму варианту (описал чуть ранее) и планируется
avatar
Про блокнот на самом деле смешно, но серьёзно. Сейчас уже такое время, когда куча людей, каких-никаких PC-шных программистов, впадает в ступор, когда речь заходит про bat-файлы и блокнот. Они же привыкли работать в IDE, а тут по двойному клику ничего само не открывается и ничего не понятно. И как ни странно, если помочь им это препятствие преодолеть, у них что-то потом получается, хотя казалось бы, не осилил batch, куда тебе ассемблер. Просто дополнительный психологический барьер.
Мне кажется, это уже перебор. Считаю, что данный туториал сделан как раз как надо. Есть исходник с комментарием в каждой (!) строчке. Есть ссылки на компилятор и на уже настроенный эмулятор, есть пошаговая инструкция как запустить. Что ещё нужно то? А дальше всё зависит от человека. Вопросы скорее могут возникнуть по коду («а что такое регистр?»), но Википедию никто не отменял. А дальше уже — открывай список мнемоник z80, схему организации памяти ZX Spectrum и так далее.

Bat-ы вполне себе встречаются, я уже не говорю про *nix-пользователей, где половина вещей (как минимум) делается в терминале. Опять же, по поводу IDE, это смотря какой ещё. Пока какой-нибудь Eclipse настроишь, ещё и не такое гуглить придётся :)
avatar
По поводу того, что такое регистр z80, написана куча книг и статей. По поводу того, как за пять минут этот регистр оживить средствами 2016 года, эти книги по понятным причинам молчат. Нет смысла учить тому, как работает процессор, зато есть смысл снизить порог вхождения и надеяться, что это снижение реально что-то изменит.
avatar
avatar
emuzwin forever! Инструкция выглядит так: запускаем, жмём кнопочку асм, пишем код, жмём compile, снимаем с паузы. Всё :)
avatar
без стеба. мне лень(да и не хочу — унриал форева) устанавливать — можно скриншоты такого использования? и насколько оно удобно для проекта?
avatar
Неа, не слушай меня, я один фан этого способа ибо есть ньюанс, он не работает на винде выше 7-ой :) Не надо устанавливать, распаковываешь и запускаешь. Жмёшь tools-assembler, открывается окно встроенного в эмуль ассемблера, пишешь туда код, жмёшь compile, прога уже в памяти, снимаешь эмуль с паузы и она работает. Дебагер с мышкой, тайминги класики — мне с головой хватает.

По удобству не знаю, я сделал 10 игр и сколько-то там демок. Никакого дискомфорта!

avatar
так-то прикольно, но не мое) да и на планшете восьмерка, а комп с семеркой успешно трудится поставщиком «кабельного» телеелевиденья и переехал за телевизор)
avatar
судя по скриншоту — эмулятор уже не анриал, и он не работает выше 7ой?
avatar
Nuts_ да, не анрил, emuzWin это эмулятор. В нём есть встроенный асм, всё в одном флаконе. В современных реалиях в принципе всё работает и выше 7-ой и в линуксе, вообще везде где есть virtualbox c winXP, например ;) Но это уже путь война и не подходит к определению быстрого старта :)
avatar
emuz помню еще без Win — DOS версию
avatar
Блин. Я что-то ща очень пожалел, что живу на десятке)
avatar
VirtualBox и вперёд!
avatar
Только в Emuzwin можно прогу назад отматывать. Бесценно для дебага.
avatar
Вообще не понимаю, как это работает. Как-то на основе машины времени, я полагаю?
  • sq
  • +4
avatar
Добавлю немного копеек. Часто возникают вопросы по созданию и запуску .tap
Берется Pasmo, пишется:

 org #9000

start
<strong>свой код здесь</strong>
END start



сборка:

pasmo --tapbas cald.asm cald.tap label.txt
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.