cmp – команда процессора для сравнения чисел. Реально она изменяет значения флагов . Обычно после команды cmp используются команды условного перехода. Таким образом, используя последовательно cmp и команды условного перехода, можно организовывать условные операторы, циклы и так далее. Покажем на примере реализацию некоторых циклов Паскаля на Ассемблере: Пусть, например, нам надо организовать условный оператор: Если eax<>ebx, то первое иначе второе. Это можно сделать так:
   cmp eax, ebx; {сравниваем eax с ebx}
   je @IfNot; {если равны, то переходим на иначе}
   ...... {выполняем первое}
   jmp @EndIf; {идём в конец if, чтобы второе не выполнять}
@IfNot:
   ...... {выполняем второе}
@EndIf:
Если ветка "иначе" не требуется, то задача только упрощается:
   cmp eax, ebx;
   je @IfNot;
   ...... {выполняем действие оператора if}
@IfNot:
То есть если условие выполняется, мы никуда не переходим, но если не выполняется, то выполняем прыжок вперёд. Циклы организуются ничуть не сложнее. Например, пусть нам надо выполнить цикл repeat ...... until eax=5; Это делается так:
@repeat:
   ......
   cmp eax, 5;
   jne @repeat; {если eax не равно 5 то повторяем}
Цикл while организовывается так: пусть, например, нам надо организовать цикл while eax=10 do begin ... end; Вот как это делается:
@while:
   cmp eax, 10;
   jne @EndWhile; {Если не равно, выходим из цикла}
   ......
   jmp @while; {повторяем цикл}
@EndWhile:
Теперь рассмотрим цикл for. Например, пусть нам надо организовать такой цикл: for eax:=2 to 9 do ... Это делается так:
   mov eax, 2;
@For:
   ......
   inc eax;
   cmp eax, 9;
   jg @For;
{то есть при девятке мы даём возможность циклу выполниться}
Если переменная цикла нам в цикле не нужна, то дело можно упростить: пусть, например, цикл должен выполниться 10 раз. Тогда организуем его так:
   mov eax, 10;
@Cycle:
   ......
   dec eax;
   jnz @Cycle;
То есть получается как бы цикл в обратном направлении (переменная цикла сначала 10, затем 9, 8, ..., и после цикла 0). Если переменная цикла не нужна в цикле и нам заранее известно требуемое число выполнений цикла, и если оно мало (2 или 3), то можно просто скопировать тело цикла нужное число раз, чтобы не тратить процессорное время на лишнюю обработку переходов (если цикл состоит из одной инструкции, то имеет смысл её копировать даже 10 раз, чем организовывать цикл). Памяти расходуется, конечно, больше, но при современных объёмах памяти даже ста килобайт на цикл не жалко, если он должен будет часто выполняться, и если это действительно даст реальный выигрыш в производительности
Теперь поговорим о том, как писать сложные условия (и, или, не,...). Пусть, нам, например, надо сделать следующее: if (eax=5) and (ebx=4) then ... Это делается так:
   cmp eax, 5; jne @IfNot; {если не выполнилось первое, выходим}
   cmp ebx, 5; jne @IfNot; {если не выполнилось второе, выходим}
   ......
@IfNot:
Немного сложнее организовать условие ИЛИ. Оператор if (eax=7) or (ebx=9) then ... делается так:
   cmp eax, 7; je @if; {Если первое выполнилось, делаем}
   cmp ebx, 9;
   jmp @EndIf; {Если второе выполнилось, делаем}
@if:
   ......
@EndIf:
Аналогичным образом можно организовывать условия, типа (первое) and (второе) and (третье) and ..., или (первое) or (второе) or (третье) or ... На Ассемблере можно организовать любое условие таким образом, если в нём нет сложных отрицаний (есть только простые отрицания. Сложным отрицанием назовём отрицание коньюнкции или дезьюнкции нескольких условий, например, not ((eax=5) and (ebx=7)). Простые отрицания – это отрицания вида not eax=5, все условия под простыми отрицаниями могут быть преобразованы к обратному виду (в данном случае not eax=5 это то же самое, что и eax<>5)). К такому виду можно привести любое сложное условие, используя законы Де-Моргана. Если же неохота преобразовывать условие, то используйте другие методы, или пишите их на Паскале (обычно программист, думающий на Ассемблере, не заворачивает сложные условия, они обычно возникают, когда программа переводится с Паскаля на Ассемблер)