Регистры и флаги процессора простыми словами

Если инструкции ассемблера — это действия процессора, то регистры — его рабочие ячейки. Процессор постоянно кладет туда значения, сравнивает их, меняет и использует для переходов

Флаги — это маленькие признаки результата последней операции. Например: результат равен нулю? Был перенос? Получилось отрицательное число? На этих признаках строятся условия

Что такое регистр

Регистр — очень быстрая ячейка внутри процессора

Условный пример:

mov ax, 10
add ax, 5

Мы положили 10 в ax, потом прибавили 5. Теперь в ax лежит 15

В x86-семействе встречаются имена:

  • ax — 16-bit;
  • eax — 32-bit;
  • rax — 64-bit;
  • bx, ebx, rbx;
  • cx, ecx, rcx;
  • dx, edx, rdx.

Названия зависят от режима и архитектуры

Почему регистры разные по размеру

Исторически x86 развивался от 16-bit к 32-bit и 64-bit. Поэтому у одного семейства регистров есть разные имена

Очень упрощенно:

AX  -> часть EAX
EAX -> часть RAX

Новичку не нужно сразу знать все детали. Достаточно понять: регистр имеет размер, и команда должна подходить к этому размеру

Что такое флаги

После операций процессор выставляет флаги

Пример:

mov ax, 5
sub ax, 5

Результат ax стал 0. Значит, Zero Flag будет выставлен

Zero Flag часто используют после сравнения:

cmp ax, 5
je equal_label

je сработает, если сравнение показало равенство

CMP и флаги

cmp можно понимать как вычитание без сохранения результата

cmp ax, 10

Процессор как будто проверяет:

ax - 10

но ax не меняет. Меняются флаги

Если ax равен 10, результат сравнения нулевой, и Zero Flag выставлен

Частые флаги

ФлагСмысл простыми словами
ZFрезультат равен нулю
CFбыл перенос/заем в беззнаковой арифметике
SFрезультат имеет знак минус
OFпереполнение для знаковой арифметики

На первом этапе чаще всего встречается Zero Flag, потому что он связан с je и jne/jnz

Условные переходы

cmp ax, 10
je equal_label
jne not_equal_label

je — перейти, если равно

jne — перейти, если не равно

jnz часто означает jump if not zero. После cmp он часто используется как "не равно", потому что если результат сравнения не ноль, значения разные

Мини-пример

mov ax, 7
cmp ax, 7
je is_equal

mov bx, 0
jmp end

is_equal:
mov bx, 1

end:

Если ax равен 7, в bx попадет 1. Если нет — 0

Почему флаги не нужно менять руками на старте

Флаги обычно выставляются инструкциями:

  • add;
  • sub;
  • cmp;
  • test;
  • арифметическими операциями.

Новичку важнее научиться читать: какая команда выставила флаг и какой переход после нее используется

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

Думать, что cmp сохраняет результат

cmp не меняет операнды. Он меняет флаги

Путать je и jmp

jmp — безусловный переход. je — переход только при равенстве

Не учитывать размер регистра

Команды должны работать с подходящими размерами операндов

Копировать переход без понимания предыдущей команды

Переход смотрит на флаги. Если перед ним была другая инструкция, флаги могли измениться

Мини-задания

  1. Положи 5 в ax.
  2. Сравни ax с 5.
  3. Если равно, положи 1 в bx.
  4. Если не равно, положи 0.
  5. Измени значение ax и проверь другой путь.

Ответы на эти вопросы могут быть для вас полезными

Что такое регистр процессора?

Это быстрая внутренняя ячейка процессора, с которой инструкции работают напрямую

Что хранится во флагах?

Флаги хранят признаки результата операции: ноль, перенос, знак, переполнение и другие состояния

Что делает Zero Flag?

Показывает, что результат операции равен нулю. Часто используется после cmp

Почему после cmp можно делать je?

Потому что cmp выставляет флаги, а je проверяет флаг равенства через Zero Flag

Нужно ли знать все флаги сразу?

Нет. Начни с ZF, cmp, je, jne/jnz. Остальные добавляй по мере задач

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

Если вы собираете тему по шагам, рядом лучше открыть:

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x