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


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


n data.bin r cx 200 f 0 l 200 0 e 0 "Заголовок" 0 e a0 "Текст сообщения для вывода" 0 m 0 l 200 100 w q

Все аргументы подготовлены; настало время рассмотреть вызовы самих функций. При нормальном ходе исполнения очередная инструкция извлекается из памяти по адресу, содержащемуся в регистре EIP. В процессе декодирования сначала определяется длина инструкции, и это значение прибавляется к содержимому регистра EIP, который, таким образом, указывает на следующую инструкцию.

Но существуют отклонения от этого последовательного хода исполнения; одним из таких случаев является вызов функций. В этом случае содержимое регистра EIP автоматически сохраняется в стеке (это значение называется адресом возврата), а в регистр EIP заносится операнд инструкции вызова функции, который является адресом первой команды вызываемой функции. В свою очередь, последней командой функции должна быть инструкция возврата управления, которая восстанавливает сохраненный ранее в стеке адрес возврата в регистре EIP, и управление переходит на следующую после вызова функции инструкцию. В результате вызов функции выглядит так, будто это обычная одиночная инструкция и не было всего этого "путешествия" куда-то в другие области адресного пространства.

Рассмотрим инструкции вызова функций (эта группа обозначается на ассемблере мнемоникой CALL). Инструкция с непосредственным смещением:

11101000 &lt4 байта смещения&gt

Следующие за опкодом 4 байта являются знаковым смещением относительно адреса следующей инструкции: это значение добавляется к содержимому EIP, и полученное число является конечным адресом. Причем если самый старший бит смещения равен 1, число рассматривается как отрицательное (представленное в виде двоичного дополнения). Не вдаваясь в детали, преобразование положительных двоичных чисел в отрицательные и обратно осуществляется так: все нули исходного числа меняются на единицы, а единицы - на нули, и к этому числу добавляется единица. Например, в случае байта, 00000001 - это +1, меняем на 11111110 и добавляем 1, получая 11111111 - это будет -1 в двоичном виде.




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



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