Разместите нашу кнопку!

Новые статьи:

Programming articles

Создание сайтов на шаблонах

Множество вариантов работы с графикой на канве

Шифруем файл с помощью другого файла

Перехват API функций - Основы

Как сделать действительно хороший сайт

Создание почтового клиента в Delphi 7

Применение паскаля для решения геометрических задач

Управление windows с помощью Delphi

Создание wap сайта

Операционная система unix, термины и понятия

SQL враг или друг

Возникновение и первая редакция ОС UNIX

Оптимизация проекта в Delphi

Ресурсы, зачем нужны ресурсы

Термины программистов 20 века

Советы по созданию собственного сайта с нуля

Шифруем файл с помощью пароля

Фракталы - геометрия природы

Crypt - Delphi программа для шифрования

Рассылка, зачем она нужна и как ее организовать?

Учебник по C++ для начинающих программистов

Уроки для изучения ассемблера

Загадочный тип PCHAR

Средства по созданию сайтов

Операторы преобразования классов is и as

Borland Developer studio 2006. Всё в одном

Создание базы данных в Delphi, без сторонних БД


Software engineering articles



Assembler&Win32. Курс молодого бойца. Урок 15.

Некоторые функции Win32.

     На прошлом уроке мы написали первое оконное приложение на ассемблере. На прошлом уроке я вам рассказал структуру ЛЮБОГО оконного приложения. Сегодня я вам расскажу (т.е. опишу) несколько функций API.

    Как я вам уже рассказывал, в Win32 есть только API функции. ЛЮБОЕ приложение в ЛЮБОМ случае должно использовать АПИ функции (по крайней мере, для того чтобы оно могло нормально завершиться). Эти функции находятся в библиотеках kernel32.dll, user32.dll, gdi32.dll (3 классические библиотеки) и др. Функции библиотеки kernel32.dll самые главные, они отвечают за работу с файлами памятью, от них никуда не денешься, user32.dll отвечает за окна и интерфейс пользователя, а gdi32.dll за "рисование" и мультимедиа. Для того, что бы использовать функции этих библиотек надо сначала их загрузить (kernel32.dll загружать не надо).

    Каждое приложение проецируется в своё собственное виртуальное адресное пространство размером в 4 ГБ, верхние 2 из которых недоступны для него. Это пространство (вернее нижние 2 ГБ) подготавливается для него: в него загружаются 2 библиотеки kernel32.dll и ntdll.dll (для Win NT) всегда по одинаковым адресам, подготавливается стек для главной нити процесса и ещё много чего. В эту память загружаются код и данные приложения. Для того, что бы операционная система знала по каким адресам надо загружать данные и код приложения она смотрит дополнительную информацию о секциях приложения в "экзе" файле. Если она этого не сделает, то она просто не будет знать, куда спроецировать код и данные, следовательно, все обращения к памяти будут неверными. (Мы, конечно, помним что под записью mov eax, [value] понимается помещение в регистр eax содержимого некого адреса памяти, которую подразумевает метка value , эта метка подразумевает некий фиксированный адрес, все адреса рассчитываются при компиляции программы и вам об этом задумываться не надо).

    Каждое приложение в своей работе вызывает API функции, под вызовом функции подразумевается передача управления некоторому адресу, который находится в диапазоне памяти, в которую загружена библиотека, которая содержит данную функцию. Рассмотрим пример.

Call VirtualAalloc

    Как мы уже знаем слово VirtualAlloc будет заменено на некоторый адрес. Этот адрес будет соответствовать адресу точки входа функции VirtualAlloc. Потом эта функция передаёт управление функциям Native API которые находятся в библиотеке ntdll.dll. Функции Native API подготавливают процесс к переходу в режим ядра и командой sysenter переводят процесс в режим ядра и т.д. Дальше я не буду рассказывать, потому что это слишком много для одного урока.

Теперь я опишу несколько API функций для работы с памятью.

    Функция VirtualAlloc позволяет зарезервировать некоторый участок памяти заданного размера, при этом эта память полностью обнуляется.
    Вот описание этой функции из MS SDK в оригинале
LPVOID VirtualAlloc(
   LPVOID lpAddress, // address of region to reserve or commit
   DWORD dwSize, // size of region
   DWORD flAllocationType, // type of allocation
   DWORD flProtect // type of access protection
);
lpAddress -начальный адрес региона
dwSize - размер региона flAllocationType - тип резервирования может быть указана одна из 3х констант :
MEM_COMMIT эта память может быть сброшена в файл подкачки
MEM_RESERVE этот участок памяти не может быть сброшен в файл подкачки он будет присутствовать в физической памяти всегда, пока эту память процесс не ввысвободит.
MEM_TOP_DOWN не пойму для чего нужна эта константа, но она есть, она позволяет зарезервировать виртуальную память, которая будет соответствовать максимально возможному физическому адресу.
flProtect тип доступа к памяти. Могут быть использованы эти константы или их комбинации.
PAGE_READONLY
PAGE_READWRITE
PAGE_EXECUTE позволяет передавать управление этому региону попытка чтения или записи приводит к нарушению прав доступа.
PAGE_EXECUTE_READ
PAGE_EXECUTE_READWRITE
PAGE_NOACCESS
Мне кажется всё и так понятно, кому не понятно читайте MS SDK.
Функция VirtualFree обратна функции VirtualAlloc высвобождает заданный диапазон памяти.
BOOL VirtualFree(
   LPVOID lpAddress, // начальный адрес освобождаемого региона
   DWORD dwSize, // размер региона
   DWORD dwFreeType // type of free operation
);
dwFreeType метод высвобождения:
если укажете MEM_RELEASE то размер указывать не надо, если MEM_DECOMMIT, то размер надо указывать остальных различий, если указано MEM_RELEASE, то эта память высвобождается полностью.
Если функция завершилась нормально, то результат отличен от нуля.
Функция VirtualProtect позволяет изменить тип доступа к зарезервированной памяти, но не так всё просто надо ещё указать старый тип доступа.
BOOL VirtualProtect(
   LPVOID lpAddress, // начальный адрес
   DWORD dwSize, // размер
   DWORD flNewProtect, // новый тип доступа
   PDWORD lpflOldProtect // старый тип доступа
);
Вроде всё понятно.
   Функция VirtualLock блокирует участок памяти, при этом доступ к нему невозможен и одновременно не приводит к ошибке.
BOOL VirtualLock(
   LPVOID lpAddress, // начальный адрес
   DWORD dwSize // размер
);
При удачном исходе результат не равен нулю.
Функция VirtualUnlock обратная предыдущей функции.
BOOL VirtualUnlock(
   LPVOID lpAddress,
   DWORD dwSize
);
   При удачном исходе результат не равен нулю.
   Все указанные выше функции могут работать только с памятью текущего процесса.
   На сегодня хватит. Для этих целей существует MS SDK. Я объяснил только несколько функций.


Вот и конец 15 урока моего туториала.