ПРОСТЕЙШАЯ ПРОГРАММА В МАШИННЫХ КОДАХ
ПРОСТЕЙШАЯ ПРОГРАММА В МАШИННЫХ КОДАХ
Как мы уже говорили, ассемблер невысоко поднялся над машинным языком, поэтому, прежде чем бросаться с головой в программирование, будет полезно составить хотя бы несколько коротеньких программок чисто в машинных кодах. Это позволит гораздо лучше прочувствовать идеологию ассемблера и понять, как работает микропроцессор.
Большинство программ на машинном языке, имеющих возврат в Бейсик, заканчивается кодом 201 (в мнемоническом обозначении - RET), который аналогичен оператору RETURN. Поэтому простейшая программа может состоять всего из одного байта. Давайте сейчас создадим такую программу, а потом и выполним ее. Введите с клавиатуры оператор
POKE 40000,201
а затем, чтобы проверить действие полученной «программы», запустите ее с помощью функции USR, например, так:
RANDOMIZE USR 40000
Вроде бы ничего особенного не произошло - никаких видимых или слышимых эффектов. Но, по крайней мере, ваш компьютер выдержал подобное испытание и при этом не «завис» и не «сбросился» (если он исправен, конечно, на что мы надеемся). Программа нормально завершила свою работу и благополучно вышла в Бейсик с сообщением 0 OK.
Теперь попробуем запустить ее несколько иным способом. Заменим оператор RANDOMIZE на PRINT:
PRINT USR 40000
То, что вы увидели на экране - весьма существенно и может очень пригодиться в будущем. Компьютер напечатал то же самое число, которое мы использовали в качестве аргумента функции USR. Можете проверить, что это не случайное совпадение, введя строку
POKE 40001,201: PRINT USR 40001
Можете попробовать проделать то же самое и с другими адресами, только не слишком увлекайтесь, чтобы не залезть в «запрещенные» области памяти. Для подобных экспериментов лучше не выходить из диапазона адресов от 30000 до 60000, да и то лишь в том случае, если память компьютера свободна от каких-либо других программ.
Для того, чтобы каким-то образом использовать полученный результат, необходимо понять причину такого странного поведения компьютера. Ответ на эту загадку заключается в том, что USR - это функция, а любая функция, по своему определению, должна получать что-то на входе и возвращать нечто на выходе. Поэтому остается лишь выяснить сущность этих «что-то» и «нечто» - и вопрос можно считать решенным.
Как вы увидите позже, большинство процедур в машинных кодах, если это необходимо, получают входные параметры и возвращают значения на регистрах. Как правило, это оказывается наиболее удобно. Поскольку функция USR предназначена для вызова машинных процедур, то и она может обмениваться числовыми данными с программой на Бейсике также через регистры, а именно - через регистровую пару BC. В качестве входного параметра используется аргумент функции, а на выходе значение пары BC передается бейсик-программе. А так как в приведенных выше примерах никакие регистры не изменялись, то и на экране появлялось то же самое число, которое использовалось в качестве аргумента.
Теперь модернизируем нашу программку так, чтобы содержимое регистровой пары BC изменялось. Можно, например, просто записать в нее какое-нибудь число. Обычно запись в регистры числовых значений называют загрузкой, поэтому в мнемоническом обозначении такие команды начинаются с LD (сокращение от известного вам по Бейсику слова LOAD - загрузить). А выражение «загрузить регистровую пару BC значением 1000» записывается как
LD BC,1000
Эта команда всегда состоит из трех байт: первый равен 1, а второй и третий соответствуют двухбайтовому представлению числа в памяти. Таким образом, программа из двух команд
LD BC,1000 RET
в памяти будет представлена последовательностью кодов
1, 232, 3 и 201
Введите их последовательно, начиная, например, с адреса 60000 и выполните закодированную программку оператором
PRINT USR 60000
Если вы ничего не напутали, то на экране должно появиться число 1000.
Надо думать, на этих примерах вы уже почувствовали «прелесть» программирования в машинных кодах и догадались, что подобным методом может пользоваться только сумасшедший или неукротимый фанатик. Однако и фанатик в конце концов понимает, что лучше все же воспользоваться ассемблером, благо фирма HISOFT подарила синклеристам весьма недурную реализацию этого языка, по многим параметрам могущую считаться вполне профессиональной. (Лучшей реализацией языка ассемблера для компьютеров семейства ZX Spectrum считается транслятор фирмы OCEAN Software из пакета Laser Genius, однако ассемблер фирмы HISOFT остается непревзойденным по минимальному объему занимаемой самим транслятором памяти и, соответственно, максимальному размеру области, отводимой для создаваемого им кода программы. Как и Бейсик 48, этот ассемблер использует несколько усеченный строчный текстовый редактор. Это, конечно, немного хуже, чем экранный редактор (как, например, в Бейсике 128), но за все приходится чем-то расплачиваться - Примеч. ред.)