Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #35, ОКТЯБРЬ 2003 г.

Игры настоящих кодеров

Shen (_shen_@mail.ru)

Спецвыпуск Xakep, номер #035, стр. 035-054-3


Итак, следующая команда Redcode. «JMP A» передает управление на команду с адресом A (как ты помнишь, адресация идет относительно текущей команды). Так что затруднений с другим классическим воином – Wait, у тебя возникнуть не должно. Сохрани следующую строчку в файле wait.red:

JMP 0

Да! Он ничего не делает, а просто каждый цикл передает управление на себя же, т.е. находится в бесконечном цикле. Вот с этим-то «воином» мы и стравим нашего Импа. File->Load, выбирай Импа и Вэйта, жми Run. Вопрос на засыпку: кто победит? А вот и нет! Не победит никто - pMARS объявит ничью! Почему? Помнишь, я давал два основных правила CoreWar? Я говорил, что программа проигрывает, только если попытается выполнить данные, а не код? То-то же. Имп, дойдя до того места, где стоит зацикленный Вэйт, перепишет его «JMP 0» своим «MOV 0, 1», и Вэйт сам превратится в Импа! То есть на поле боя будет два Импа, что, как мы уже говорили, приведет к ничьей! Получается, Имп вообще не способен победить кого-либо? В принципе, да – Имп может выиграть только в том случае, если вражеская программа самоуничтожится. Впрочем, как и Вэйт. Тем не менее, идея, положенная в основу Импа, используется во многих эффективных программах-бойцах.

Тебе, наверное, уже не терпится посмотреть на полноценную программу, которая сможет победить хотя бы Вэйта? Мы напишем такую программу, но для этого нам нужно узнать еще две команды и познакомиться с другими способами адресации.

ADD, DAT, @ и #

«ADD A, B» прибавит команду с адресом A к команде с адресом B и запишет результат по адресу B. Такая форма ADD нас не устраивает, поэтому перепишем ее так: «ADD #A, B». Теперь это означает: прибавить число A ко второму операнду команды с адресом B (чаще говорят «к B-полю команды с адресом B»). Слишком запутанно? Смотри:

ADD #1, 1 ; <---

MOV 0, 0

Команда ADD в данном примере прибавит число один к B-полю инструкции MOV, превратив эту команду в Импа: «MOV 0, 1». Т.е. знак # означает, что имеется в виду не адрес, а конкретное число.

Что делает команда MOV в следующей программе?

MOV 0, @1 ; <---

ADD #1, 1

Она копирует саму себя по адресу, на который указывает второй операнд команды по адресу 1. Ты помнишь, что все адреса рассчитываются относительно текущей инструкции? По адресу 1 находится команда ADD, второй операнд которой равен 1. Следовательно, MOV копирует саму себя по адресу, равному единице относительно ADD. Таким образом, после выполнения первой инструкции, поле будет выглядеть так:

MOV 0, @1

ADD #1, 1 ; <---

MOV 0, @1

Понятно? Теперь разберемся поподробнее, как погибает процесс. Хочешь посмотреть на программу, которая проигрывает бой с Вэйтом? Смотри:

Назад на стр. 035-054-2  Содержание  Вперед на стр. 035-054-4