Ассемблер

CMP в ассемблере

CMP в ассемблере используют для сравнения двух значений. Инструкция работает как проверочное вычитание: выставляет флаги процессора, но не сохраняет результат и не меняет операнды. Поэтому cmp почти всегда читают вместе со следующей командой условного перехода

Базовая запись:

cmp eax, ebx
je equal

Если eax и ebx равны, переход je equal сработает. Если не равны, выполнение пойдет дальше

Синтаксис CMP

В Intel/NASM-синтаксисе:

cmp левый_операнд, правый_операнд

Примеры:

cmp eax, 0
cmp eax, ebx
cmp byte [flag], 1
cmp dword [rbp-4], 10

Операнды должны быть совместимыми по размеру. Если сравниваете байт, указывайте байт. Если сравниваете 32-битное значение, используйте 32-битный регистр или явный размер памяти

Пример проверки равенства

mov eax, 42
cmp eax, 42
je answer

mov ebx, 0
jmp done

answer:
    mov ebx, 1

done:

После cmp eax, 42 процессор выставит ZF, потому что значения равны. Переход je означает «jump if equal»

Пример проверки неравенства

cmp eax, 0
jne not_zero

Если eax не равен нулю, переход выполнится. jne и jnz часто используются как близкие варианты после cmp: не равно и не ноль

Больше и меньше

Для знаковых чисел:

cmp eax, ebx
jl less
jg greater

Для беззнаковых чисел:

cmp eax, ebx
jb below
ja above

Если вы сравниваете -1 и 1, signed и unsigned логика дадут разный смысл. В 32-битном виде -1 — это FFFFFFFFh, а как unsigned это огромное положительное число

Порядок операндов

cmp eax, ebx и cmp ebx, eax — разные проверки для «меньше» и «больше»

cmp eax, ebx
jl eax_less_than_ebx

читается как:

если eax меньше ebx

Если поменять операнды местами, условие изменится

CMP в цикле

mov ecx, 0

loop_start:
    add ecx, 1
    cmp ecx, 10
    jl loop_start

Пока ecx < 10, цикл возвращается к loop_start. Как только ecx станет 10, переход jl больше не сработает

CMP и TEST

Для проверки нуля можно писать:

cmp eax, 0
je zero

Можно встретить и так:

test eax, eax
je zero

test часто компактнее для проверки нуля, но cmp проще для понимания, потому что явно сравнивает с конкретным значением

Частые ошибки

Думают, что CMP меняет операнд

После cmp eax, 5 значение eax остается прежним

Сравнивают память с памятью

На x86 многие формы не позволяют напрямую сравнить два адреса памяти. Обычно одно значение сначала загружают в регистр

Смешивают signed и unsigned переходы

Запомните: jl/jg для signed, jb/ja для unsigned

Меняют флаги между CMP и переходом

Ставьте переход сразу после сравнения, пока не уверены в каждой инструкции

Что почитать дальше по ассемблеру

Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x