Ассемблер

CMP asm: что делает инструкция сравнения

cmp в asm — это инструкция сравнения. Она берет два операнда, выполняет внутреннее вычитание, не сохраняет результат и обновляет флаги процессора. После нее обычно ставят условный переход: je, jne, jl, jg, jb, ja

В NASM/Intel-синтаксисе пример выглядит так:

cmp eax, 10
je equal

В AT&T-синтаксисе, который часто встречается в выводе GCC/GDB на Linux, порядок записи другой:

cmpl $10, %eax
je equal

Обе записи сравнивают значение регистра eax с числом 10, но синтаксис отличается

Синтаксис в Intel/NASM

cmp регистр, значение
cmp регистр, регистр
cmp память, регистр
cmp регистр, память

Примеры:

cmp eax, 0
cmp eax, ebx
cmp byte [flag], 1
cmp qword [rbp-8], 100

В Intel-синтаксисе первый операнд часто воспринимают как левую часть сравнения: cmp eax, ebx означает сравнить eax с ebx

Синтаксис в AT&T

AT&T-синтаксис пишет источник перед назначением и добавляет размер в имя инструкции:

cmpb $1, -1(%rbp)
cmpl $10, %eax
cmpq %rax, %rbx

Суффиксы:

  • b — byte, 1 байт;
  • w — word, 2 байта;
  • l — long, 4 байта;
  • q — quad, 8 байт.

Запись:

cmpl $10, %eax

означает сравнить 32-битное значение eax с 10

Какие флаги меняет cmp

После cmp особенно важны:

  • ZF — значения равны;
  • CF — нужен для unsigned-сравнений;
  • SF — знак результата;
  • OF — переполнение для signed-сравнений.

Сами регистры не меняются. Если было:

mov eax, 4
cmp eax, 9

после cmp в eax все равно 4

Как выбрать переход

Для равенства:

cmp eax, ebx
je equal
jne not_equal

Для signed-сравнения:

cmp eax, ebx
jl less
jg greater

Для unsigned-сравнения:

cmp eax, ebx
jb below
ja above

Если вы сравниваете обычные положительные счетчики массива, часто нужны unsigned-переходы. Если сравниваете числа, которые могут быть отрицательными, нужны signed-переходы

Пример: проверка диапазона

Пусть в eax лежит возраст. Нужно проверить, что он от 18 и выше:

cmp eax, 18
jl too_young

mov ebx, 1
jmp done

too_young:
    mov ebx, 0

done:

Такой код использует jl, потому что возраст записан как обычное знаковое число. Если значение гарантированно неотрицательное, можно использовать и unsigned-логику, но в учебных примерах signed-переход легче объяснить

Частые ошибки в cmp asm

Считать cmp полноценным if

cmp только готовит флаги. Сам выбор делает следующая команда

Забыть, что порядок важен

cmp eax, ebx и cmp ebx, eax дают разные флаги для «меньше» и «больше»

Смешать синтаксисы

Такой код не является нормальной одной записью:

cmp %eax, 10

Либо пишите NASM/Intel, либо AT&T

Использовать переход не того типа

jl и jb не одно и то же. Первый для signed, второй для unsigned

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

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

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

Настройки cookie

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