Метки и безусловный переход jmp
Урок вводит метки и безусловный переход — фундамент всех ветвлений и циклов.
Метка — это имя для адреса в коде; переход на метку меняет значение RIP и продолжает исполнение оттуда.
Код исполняется не всегда по порядку
По умолчанию команды идут сверху вниз, потому что RIP сдвигается на следующую. Но команда jmp метка заставляет RIP прыгнуть в другое место — и исполнение продолжается там. Это единственный способ сделать в процессоре циклы, ветвления и функции.
mov rax, 1
jmp dalshe ; перепрыгнуть через следующую строку
mov rax, 999 ; эта команда НЕ выполнится
dalshe:
add rax, 10 ; сюда мы прыгнули, rax = 11Метки — это просто адреса
Когда NASM видит dalshe:, он запоминает адрес этого места. В машинном коде никаких имён нет — jmp превращается в «прибавить к RIP такое-то смещение». Имена нужны только людям; процессор оперирует числами-адресами.
Бесконечный цикл одной командой
Простейший вечный цикл — переход на самого себя:
loop_forever:
jmp loop_forever ; RIP всё время возвращается сюдаЧтобы цикл был полезным и завершался, внутри нужна проверка с условным переходом — об этом следующие уроки.
Как работает под капотом
Смоделируем «прыжок» на Python через индекс «команды», имитируя RIP:
program = ["mov", "jmp->4", "skip", "skip", "add"]
rip = 0
trace = []
while rip < len(program):
cmd = program[rip]
trace.append((rip, cmd))
if cmd == "jmp->4":
rip = 4 # прыжок: меняем RIP напрямую
else:
rip += 1 # обычный шаг вперёд
for step in trace:
print(step)Вывод:
(0, 'mov') (1, 'jmp->4') (4, 'add')
Видно, что команды с индексами 2 и 3 пропущены — RIP перепрыгнул через них. Так же реальный jmp заставляет процессор пропускать или повторять участки кода.
Частые ошибки
- Забыть двоеточие в определении метки.
dalsheбез:— это не метка, а попытка использовать имя. - Случайно «провалиться» в метку. Если перед меткой нет
jmp/ret, код просто продолжит исполняться в неё. - Вечный цикл без выхода.
jmpна себя без условия внутри зависнет навсегда.
Итог
jmp меткаменяет RIP и продолжает исполнение с другого места.- Метка — это имя адреса; в машинном коде остаются только смещения.
- Без переходов кода были бы только линейными — нет ни циклов, ни ветвлений.
- Полезный цикл требует условного перехода внутри, иначе он бесконечен.