Показать сообщение отдельно

  #4  
Старый 13.08.2008, 01:04
luz3r
Banned
Регистрация: 23.02.2008
Сообщений: 268
С нами: 9586096

Репутация: 850
Post

Ассембли. Урок III - Сравнения и переходы (более подробно)

Привет. На этом уроке поговорим про операторы cmp & условные переходы более подробно. Для начала обратите внимание на таблицу условных переходов. Вы уже видели нечто подобное на прошлом уроке:



Теперь давайте посмотрим на практике. Есть код:

Цитата:

1) mov eax,32 ; в EAX 32h

2) mov ebx,33 ; в EBX 33h

3) cmp eax,ebx ; сравниваем EAX c EBX

4) jne metka ; Если не равны то прыгаем на metka

5) sub eax,eax ; иначе обнуляем EAX

metka:

6) invoke ExitProcess,0 ; завершаем процесс
Разберём каждую инструкцию:

1) mov - инструкция, которая присваивает значения. В данном случаи мы присваиваем регистру EAX число 32h (hex)

2) Аногогично, только теперь регистру EBX присваиваеться 33h

3) cmp - оператор сравнения (Compare - сравнивать). Сравнивает EAX c EBX и взависимости от результата выставляет соответствующие арифметические флаги (у нас ZF, SF, CF - но не подумайте что это все флаги!)

4) Наш условный переход, чтобы его понять обратимся к таблице. Смотрим тип операндов - любые, значит не имеет значения, со знаком числа или без. Далее смотрим критерий условного перехода - 1операнд НЕ РАВЕН 2операнду. И третие - смотрим значение флага, в данном случаи это флаг "нуля" (ZF - Zerro Flag). Итак из таблицы видно что, чтобы мы прыгнули на метку - регистры EAX & EBX не должны быть равны и флаг нуля устанавливаеться в 0(нуль). То есть если они не равны - мы прыгаем на метку "metka"

5) Так как переходу быть - процессор не выполняет эту инструцкию. Она предназначена для вычитания. То есть если бы перехода не было она бы вычла из EAX, EAX (значения) - тем самым обнулив его.

6) Уже до боли знакомый вам вызов функции API ExitProcess, который просто завершит программу.

Если бы мы в 4) пункте написали бы не JNE a JZ то мы бы не прыгнули на метку, так как регистры EAX & EBX не равны между собой.

Для полноты всей картины давайте воспроизведём всё выше описаное в полноценную программу:

Цитата:

include 'D:\FASM\include\win32ax.inc'

.code

start:

mov eax,32 ; в EAX 32h

mov ebx,33 ; в EBX 33h

cmp eax,ebx ; сравниваем EAX c EBX

jne metka ; Если не равны то прыгаем на metka

sub eax,eax ; иначе обнуляем EAX

metka:

invoke ExitProcess,0 ; завершаем процесс

.end start
Вот и весь урок. Можно эксперементировать задавая разные значения регистрам и изменяя прыжок - так вы быстрее поймёте. Есстественно нужно это делать в отладчике. Возьмите Olly. Кстати вот этот наш кусок кода в отладчике выглядит следующим образом:



Красная стрелочко означает что сейчас произойдёт переход, и я ещё там написал что флаг нуля = 0 (нуль), чтобы не постить весь экран от Olly. А вот Olly лучше скачайте и посмотрите сами!
 
Ответить с цитированием