allasm.ru |
|
В апокрифических преданиях говорится, что сам Баал был не против побаловаться на досуге ассемблером, пока не написал на нём свой Бейсик. Так почему бы и нам этим не заняться? В прошлой главе данного фолианта я обещал рассказать вам о том, как заклинать инструкцию NOP. Это просто и может это сделать любой, владеющий основами ассемблера. Но для начала вы должны узнать, что такое опкод. На самом деле я уверен, что почти любой из взявшихся за изучение заклинания кода знает, что это такое, но, тем не менее, поведаю это на случай, если кому-то это неизвестно. Как вам должно быть известно, ассемблеры переводят инструкции из понятной и запоминающейся (мнемонической) человеку формы в форму, понятную ЭВМ - в машинный код. Инструкции в машинном коде имеют определенный формат и состоят из нескольких полей, главным из которых является опкод - код операции. А некоторые, простые инструкции, состоят только из опкода и других полей у них нет. Одной из таких инструкций является NOP. Её опкод - 90h. У этой инструкции нет параметров, поэтому знания её опкода достаточно для заклинания. Вот пример программы:
Надеюсь, у читателей этой главы, новоявленных заклинателей, не возникнет вопроса, почему эта программа ничего не делает. А для тех, у кого возникнет, поясняю: инструкция NOP ничего не делает (отсюда и её мнемноника - No OPerations). Если быть более точным, то NOP имеет тот же опкод, что и инструкция XCHG EAX,EAX, однако результат (отсутствие изменений) от этого не меняется. Но NOP - это не очень интересно. Безусловно, поначалу заклинание внушает, однако на практике оно не очень полезно. Было бы неплохо, если бы мы могли заклинать что-нибудь более полезное - например, увеличивать или уменьшать значение в eax на 1. Это возможно. Для этого есть мнемоники INC (INCrement) и DEC (DECrement). Опкод INC EAX - 40h, опкод DEC EAX - 48h. Далее я приведу текст программы, в которой в eax кладётся число 10, затем содержимое eax увеличивается на 1 пять раз, потом - трижды уменьшается на 1. Используя абак несложно посчитать, что в результате должно получиться 12. Это число мы отобразим с помощью MessageBox.
Скомпилировав и запустив программу можно убедиться, что в результате получается 12. Наше заклинание верно и ошибок нет. На досуге можете поэкспериментировать с PUSH EAX (опкод 50h) и POP EAX (опкод 58h). Однако этого вам может показаться мало. Возможно, вы захотите сделать заклинание PUSH EBX или даже INC EDX - и это вполне вам по силам! Я дам вам общую формулу для этих инструкций, когда операндом является регистр (именно регистр, а не ячейка памяти, причём 32-х битный!). Общая формула такова: Базовый опкод + номер регистра Базовые опкоды:
Номера регистров:
Используя эту формулу легко вычислить, например, опкод PUSH EDX: 48h+2=4Ah. Я рекомендую потренироваться в составление простых заклинаний на основе приведённых выше. Довольно практики, перейдём к теоретическим вопросам. Какой длины может быть опкод? Для процессоров семейств x86 он может быть длиной до 3 байт. Также, под опкод может использоваться часть байта ModR/M, о котором будет рассказано в следующих главах. Да, инструкции могут различаться по размеру. А в некоторых процессорах с другой архитектурой инструкции имеют фиксированную длину. Почему же в x86 это не так? Согласно легенде, когда интеловские гномы добывали руду для первых процессоров, они ещё не умели дробить руду на одинаковые по размеру инструкции. Знание же и умение делать это пришло позже. Но и после этого интеловские гномы продолжали дробить руду на разноразмерные инструкции, поскольку они умели это делать хорошо, а их изделия знали и использовали уже многие. Также я хотел рассмотреть, зачем понадобилось делать отдельный мнемоник для XCHG EAX,EAX - NOP. Причина, несомненно, в метафизическом смысле числа 90h. В каком-то смысле девятка (как утроенная триада) символизирует Инь и Янь, а ноль среди своих прочих значений символизирует Абсолют. Внесение такого мощного магического слова в ассемблер укрепило положение x86 на астральном плане. В следущей главе мы попытаемся поместить в EAX единицу. Более того, наша попытка окажется успешной! :) [C] Aquila / WASM.RU |