Win32asm обучение

  d8ef8794     

Еще о кодах операций


        Win32Asm Tutorial

       

назад 9- Еще об опкодах вперед

9.0 - Еще об опкодах

Здесь я расскажу еще о нескольких опкодах.

TEST

Команда Test выполняет операцию AND (логическое И) с двумя операндами и в зависимости от результата устанавливает или сбрасывает соответствующие флаги. Результат не сохраняется. Test используется для проверки бит, например в регистре:

test eax, 100b ; (суффикс 'b' означает двоичное число)

jnz смещение

Команда jnz выполнит переход, если в регистре eax третий бит справа - установлен. Очень часто комманду test используют для проверки, равен ли регистр нулю:

test ecx, ecx

jz смещение

Команда jz выполнит переход, если ecx = 0.

Стековые операции

Перед тем, как рассказать вам о стековых операциях, я сначала попытаюсь объяснить, что такое стек. Стек это область в памяти, на которую указывает регистр стека esp. Стек это место для хранения временных значений. Есть две команды, для размещения значения в стеке и извлечения его из стека: push и pop. Команда push размещает значение в стеке, а pop извлекает. Значение помещенное в стек последним, извлекается первым. При помещении значения в стек, указатель стека уменьшается, а при извлечении - увеличивается. Рассмотрим пример:

(1) mov ecx, 100

(2) mov eax, 200

(3) push ecx ; сохранение ecx

(4) push eax

(5) xor ecx, eax

(6) add ecx, 400

(7) mov edx, ecx

(8) pop ebx

(9) pop ecx

Анализ:

1: поместить 100 в ecx

2: поместить 200 в eax

3: разместить значение из ecx (=100) в стеке (размещается первым)

4: разместить значение из eax (=200) в стеке (размещается последним)

5/6/7: выполнение операций над ecx, значение в ecx изменяется

8: извлечение значения из стека в ebx: ebx станет 200 (последнее размещение, первое извлечение)

9: извлечение значения из стека в ecx: ecx снова станет 100 (первое размещение, последнее извлечение)

Чтобы узнать, что происходит в памяти, при размещении и извлечении значений в стеке, см. на рисунок ниже:



Смещение 1203 1204 1205 1206 1207 1208 1209 120A 120B
Значение 00 00 00 00 00 00 00 00 00
          ESP
       

( стек здесь заполнен нулями, но в действительности это не так, как здесь). ESP стоит в том месте, на которое он указывает)
mov ax, 4560h

push ax

Смещение 1203 1204 1205 1206 1207 1208 1209 120A 120B
Значение 00 00 60 45 00 00 00 00 00
      ESP          

mov cx, FFFFh

push cx

Смещение 1203 1204 1205 1206 1207 1208 1209 120A 120B
Значение FF FF 60 45 00 00 00 00 00
  ESP              

pop edx

Смещение 1203 1204 1205 1206 1207 1208 1209 120A 120B
Значение FF FF 60 45 00 00 00 00 00
          ESP
       

edx теперь 4560FFFFh.

CALL & RET

Команда call передает управление ближней или дальней процедуре с запоминанием в стеке адреса точки возврата.
Команда ret возвращает управление из процедуры вызывающей программе. Пример:
..code..

call 0455659

..more code..
Код с адреса 455659:

add eax, 500

mul eax, edx

ret
Когда выполняется команда call, процессор передает управление на код с адреса 455659, и выполняет его до команды ret, а затем возвращает управление команде следующей за call. Код который вызывается командой call называется процедурой. Вы можете поместить код, который вы часто используете в процедуру и каждый раз когда он вам нужен вызывать его командой call.
Подробнее: команда call помещает регистр EIP (указатель на следующюю команду, которая должна быть выполнена) в стек, а команда ret извлекает его и вовращается. Вы также можете определить аргументы, для вызываемой программы (процедуры). Это можно сделать через стек:
push значение_1

push значение_2

call procedure
Внутри процедуры, аргументы могут быть прочитаны из стека и использованы. Локальные переменные, т.е. данные, которые необходимы только внутри процедуры, также могут быть сохранены в стеке. Я не буду подробно рассказывать об этом, потому, что это может быть легко сделано в ассемблерах MASM и TASM. Просто запомните, что вы можете делать процедуры и что они могут использовать параметры.
Одно важное замечание:
регистр eax почти всегда используется для хранения результата процедуры.
Это также приминимо к функциям windows. Конечно вы можете использовать любой другой регистр в ваших собственных процедурах, но это стандарт.
[наверх]

Содержание раздела