Ассемблер для начинающих. Урок III – Сравнения и переходы (более подробно)
Опубликовал devprog на Ноябрь 4, 2008
Привет. На этом уроке поговорим про операторы 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 лучше скачайте и посмотрите сами! Пока.

Историк сказал
jne я так понимаю обязательный оператор после cmp (условие сравнения). А если мне нужно (если .. то ..) без всяких иначе?
Хел сказал
кто сказал что jne обязателен?
Rob сказал
Историк:
Если нужно если то, делай примерно вот так:
mov eax,1h
cmp eax,0h < ЕСЛИ!!!
jz @@dalee_po_kodu
mov eax,2h
… < тут любой код, например выход из процедуры
@@dalee_po_kodu: < ТО!!!
call hello_proc
taksos сказал
Я почему-то думал, что Olly – это компилятор под Linux. Разъясните, пжлст.
Rob сказал
OllyDbg – это 32б отладчик
taksos сказал
А какой еще посоветуете, только для 16 бит?
Rob сказал
например отладчик от борланд, который кстати поставляется вместе со всякими паскалями и прочими продуктами от борланд.