ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
Разработка и вызов процедур на языке ассемблера, структура стекового фрейма при работе процедуры, способы передачи и обращения к аргументам процедур, локальные переменные.Стек представляет собой непрерывный блок оперативной памяти, доступ к которому осуществляется посредством пары регистров SS и ESP. В регистре ESP хранится смещение вершины стека (то есть адрес последнего добавленного элемента). Значение ESP изменяется такими командами, как push, pop, call, ret и др. Напрямую изменять ESP программисту обычно не требуется. Стек в программе используется, во-первых, как удобное место для временного сохранения значений регистров. Во-вторых, при вызове процедуры в стек помещаются её аргументы, адрес возврата, в нём же выделяется память под локальные переменные. Для помещения значения в стек используется команда push. При вставке 4-байтового числа она вначале вычитает 4 из ESP (стек растёт в сторону уменьшения адресов), после чего по полученному адресу записывает аргумент. Пример вызова: push eax. Для извлечения аргумента из стека применяется команда pop – она выполняет обратные действия. Также имеются команды pushad и popad, позволяющие поместить и извлечь из стека сразу все 32-разрядные регистры общего назначения. Особенности написания и вызова процедур. Пример: .model flat, stdcall sample PROC uses eax ebx, a:DWORD, b:DWORD LOCAL tmp1:DWORD, tmp2:DWORD ;... ret sample ENDP В данном примере создана процедура sample. У неё имеются два аргумента a и b, оба типа DWORD. С помощью директивы uses мы указали, что в процедуре изменяются значения регистров eax и ebx – в результате ассемблер сгенерирует код, который при входе в процедуру сохранит эти регистры в стеке, а перед выходом восстановит. В процедуре имеются две локальных переменных tmp1 и tmp2 типа DWORD. Выход из процедуры выполняется командой ret. Данную процедуру можно вызвать командой: INVOKE sample, arg1, arg2 Рассмотрим, что будет находиться в стеке во время выполнения процедуры (стек растёт в сторону уменьшения адресов – на рисунке это будет сверху вниз).
В начале процедуры ассемблер вставляет примерно следующий код: push ebp; сохраним текущее значение ebp mov ebp, esp; запоминаем текущую позицию в стеке sub esp, 8; место под локальные переменные push eax;сохраняем указанные в uses регистры push ebx В конце процедуры ассемблер вставляет примерно такой код: mov esp, ebp;восстанавливаем положение в стеке на момент начала процедуры pop ebp ret 8; выходим, извлекая 8 байтов аргументов Из данного рисунка и примеров кода видно, что для доступа к аргументам и локальным переменным используется косвенная адресация со смещением относительно регистра EBP. Хотя мы для удобства можем использовать осмысленные имена наподобие arg1 или tmp2, в итоге они преобразуются ассемблером в обращение к памяти, адресуемой EBP. Директива INVOKE для вызова процедуры транслируется примерно в следующую последовательность команд: push arg2 push arg1 call sample
Не нашли, что искали? Воспользуйтесь поиском:
|