О недокументированных командах
(С) Георгий Новиков,
г.Серпухов, 1995.
При просмотре очень многих программ часто встречаются команды типа: #ED #6Е; #ED #7Е; #ED #55 и т.д. Это так называемые недокументированные команды. При поиске их в справочниках натыкаешься на пустое место, ассемблеры и дизассемблеры эти команды, как правило, не понимают.
На самом деле механизм образования недокументированной команды относительно прост. Рассмотрим пример образования недокументированной команды с префиксом #ED. К примеру, рассмотрим стандартную команду NEG. Она имеет код #Е0 #44. В двоичном виде это выглядит так:
11 101 101 -> #ED 01 ООО 100 -> #44
При своей работе микропроцессор Z80 после чтения управляющего байта кода операции (#ED) считывает код операции.
Рассмотрим подробнее формат команды кода операции, следующего за префиксом. Он имеет вид:
аа bbb ааа
где аа и ааа - код операции (1М_ RET_ и т.д.); bbb - либо регистр, либо модификация команды (IM1, IM2, RETI, RETN и т.д.).
ЧИТАТЕЛЬ - ЧИТАТЕЛЮ
|
Листинг 5 |
|
|
|
|
55339 08 CD 13 3D ЗЕ 01 32 OF |
Дамп |
исправлений |
|
|
|
55347 5D 21 35 99 CD D9 95 E5 |
|
|
|
|
|
|
|
55355 3E FF |
50974 |
CD |
19 97 |
|
|
|
|
|
|
|
|
|
|
|
|
В результате без всяких мате |
55063 |
18 |
ОС 2А А9 |
96 |
19 |
22 |
А9 |
риальных затрат Вы заимеете но |
55071 |
96 |
ЗА 40 СО |
С9 |
00 |
CD |
4А |
вую, прекрасно работающую версию |
55079 |
85 |
54 41 53 |
4D |
32 |
2Е |
30 |
любимого ассемблера. |
55323 |
00 |
00 00 CD |
А4 |
95 |
0Е |
OA |
★ ★ ★ |
55331 |
CD |
59 85 СВ |
79 |
СО |
79 |
0Е |
|
Так как адресация команды NEG встроенная (то есть код операции однозначно определяет, где находится операнд), то изменение параметра bbb (биты D3, D4, D5) ни к чему новому не приведет, то есть смысл команды останется прежним, зато образуется целый | набор кодов, которые выполняют одну и ту же команду (см.таблицу 1).
Команда NEG. Таблица 1.
Стандартная |
Недокументированные |
ED 44 |
ED |
54 |
|
ED |
64 |
|
ED |
74 |
|
ED |
4С |
|
ED |
5С |
|
ED |
6С |
|
ED |
1С |
Рассмотрим теперь команды возврата из INT и NMI. Это RETI и RETN. Их коды:
RETI - ED 4D RETN - ED 45
Побитовая раскладка этих команд даст нам следующее:
01 001 101 - RETI
01 000 101 - RETN
Обращаясь к формату аа bbb аа,
находим, что 01 _ 101 - код
RET_, a bbb - модификация команды:
000 - RETN
001 - RETI
ЧИТАТЕЛЬ-ЧИТАТЕЛЮ
Поскольку в данной группе команд всего две модификации, то увеличение кода bbb приведет к циклическому чередованию команд RETI и RETN:
(RLC, RRC, RL, RR, SLA, SRA,SLI, SRL, RES, SET). Пример:
Битовая |
код |
Команда |
раскладка |
команды |
|
01 000 |
101 |
ED |
45 |
RETN |
01 001 |
101 |
ED |
4D |
RETI |
01 010 |
101 |
ED |
55 |
RETN |
01 011 |
101 |
ED |
5D |
RETI |
01 100 |
101 |
ED |
65 |
RETN |
01 101 |
101 |
ED |
6D |
RETI |
01 110 |
101 |
ED |
75 |
RETN |
01 111 |
101 |
ED |
7D |
RETI |
команду RETN
Таким образом, можно записать в виде: 01 ??0 101 Пользуясь приведенным здесь алгоритмом, можно найти и остальные недокументированные команды.
(С) Сергей Колотов,
г.Шадринск, 1995.
В последнее время в машинном коде (особенно в защите различных программ), стали часто встречаться такие недокументированные последовательности байтов, которые "не периваривают" многие мониторы, в частности "M0NS 4м. Наверное, все уже знают о существовании такой "неизвестной" команды, как SLI (Shift Left and Increment ). Эта команда сдвигает все биты в байте данных влево и устанавливает нулевой бит в единицу (подробности в предыдущем номере РЕВЮ, в разделе ЭТЮДЫ). С другой стороны, мало кто знает о существовании таких команд, как например:
RLG (1Х+0),А
Действие этой команды аналогично двум стандартным:
RLC (IX+0) LD А,(IX+0)
Аналогично получаются и другие подобные команды из серии МСВМ
что эквивалентно: SRL (IX+0)
LD С,(1Х+0)
или: DD СВ 02 ЕЗ SET 4,(1Х+2),Е
что равнозначно: SET 4,(1Х+2) LD Е,(IX+2)
Общий принцип работы этих команд таков. Действие команды выполняется над байтом данных по адресу (IX+s), где s - смещение), а результат пересылается как в этот адрес, так и в требуемый регистр.
Только с командой BIT ничего не выйдет:
DD СВ 00 7F
- ожидаемое BIT 7,(IX+0),А - проверяет только седьмой бит в ячейке (IX+o), то есть фактически является операцией BIT 7,(IX+0), а регистр А здесь вообще не участвует .
Также меня заинтересовало, а что будет, если запустить на исполнение такую последовательность кодов:
DD DD DD ... DD <код команды>
Оказалось, что этот фрагмент аналогичен DD <код команды>, а лишние коды DD играют роль операции NOP.
Про недокументированные команд, основанные на использовании половинок индексных регистров IX и IY рассказывать не стану - о них уже достаточно говорилось на страницах ZX-РЕВЮ (см. например, ФОРУМ в гХ-РЕВЮ-94, N2, стр.57).
В заключение добавлю, что все приведенные здесь сведения относительно операций с IX (префикс DD), также верны и для регистра IX (префикс FD).