Win32 в машинных кодах


Простейшее приложение - часть 2


Доступ же к стеку осуществляется последовательным образом, причем операнд всегда должен иметь размер в 4 байта (для 32-разрядного режима). Для записи очередного числа значение ESP уменьшается на 4 и указывает на "чистую" область размером в 4 байта. В эту область и копируется единственный операнд соответствующей инструкции. При извлечении сохраненного числа из стека копируется 4-байтное значение, адрес которого находится в настоящий момент в ESP, а затем значение ESP увеличивается на 4 и указывает уже на предыдущее сохраненное число. Единственное, за чем необходимо следить - чтобы каждому случаю помещения данных в стек соответствовал ровно один случай извлечения этих данных из стека (это называется сбалансированностью стека).

Рассмотрим инструкции помещения данных в стек (инструкции извлечения данных из стека нам пока не понадобятся, и мы займемся ими в другой раз). На ассемблере группа данных инструкций обозначается мнемоникой PUSH. Сначала инструкция помещения в стек непосредственного значения:

011010 s 0 &ltбайты данных&gt

Эта инструкция имеет бит знакового расширения s. Если s = 0, то за опкодом следуют 4 байта, которые необходимо скопировать в стек. Если же s = 1, за опкодом следует всего один байт. Но перед тем, как поместить его в стек, производится его т.н. знаковое расширение до 4 байтов: старшие 3 байта заполняются значением старшего бита данного байта. Например, если байт данных был 01000000, он становится 00000000 00000000 00000000 01000000. Если же он был 10000000, то получается 11111111 11111111 11111111 10000000. Получившиеся 4 байта и помещаются в стек. Это позволяет сохранить знак числа, записанного в виде двоичного дополнения, и в то же время сэкономить 3 байта при операциях с небольшими числами (от -128 до +127). Например, команда помещения в стек нулевого значения (PUSH 0) кодируется так:

01101010 00000000 (6Ah 00h)

Следующая инструкция сохраняет в стеке значение общего регистра:

01010 reg

Инструкция сохранения в стеке значения регистра EAX (PUSH EAX) займет всего 1 байт: 01010000 (50h).




Начало  Назад  Вперед



Книжный магазин