; длин_тест1.квс ; Тест: два длинных перехода и два мусорных сегмента .текст .глобал _start _start: ; Инициализация регистров переместить_имм раикс, 10 ; rax = 10 (не ноль) переместить_имм рбикс, 5 ; rbx = 5 (для сравнения) ; ПЕРВЫЙ ПЕРЕХОД: переход_если_не_ноль ; ZF=0 (так как rax=10), значит jnz сработает ; Прыгаем к метке 'проверка_2', пропуская мертвый_код_1 переход_если_не_ноль проверка_2 ; --- МЕРТВЫЙ КОД 1 --- ; Этот код НЕ должен выполниться ; Добавляем "мусор", чтобы точно выйти за пределы короткого перехода переместить_имм раикс, 1 переместить_имм рдиай, 1 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 2 переместить_имм рдиай, 2 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 3 переместить_имм рдиай, 3 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 4 переместить_имм рдиай, 4 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 5 переместить_имм рдиай, 5 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 6 переместить_имм рдиай, 6 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 7 переместить_имм рдиай, 7 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 8 переместить_имм рдиай, 8 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 9 переместить_имм рдиай, 9 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 10 переместить_имм рдиай, 10 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 11 переместить_имм рдиай, 11 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 12 переместить_имм рдиай, 12 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 13 переместить_имм рдиай, 13 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 14 переместить_имм рдиай, 14 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы переместить_имм раикс, 15 переместить_имм рдиай, 15 переместить_имм рсиай, msg_dead_1 переместить_имм рдикс, len_msg_dead_1 вызов_системы ; --------------------- проверка_2: ; ВТОРОЙ ПЕРЕХОД: переход_если_равно ; Сравниваем rax (10) и rbx (5) -> ZF=0 сравнить раикс, рбикс ; ZF=0, значит je НЕ сработает. ; Мы хотим прыгнуть МИМО мертвого кода 2, если ZF=0 (т.е. когда НЕ равны). ; У нас нет инструкции 'переход_если_не_равно' (jne), но она эквивалентна 'переход_если_не_ноль' (jnz) для флага ZF. ; Однако, у нас есть 'переход_если_равно' (je), который сработает при ZF=1. ; Мы хотим, чтобы переход НЕ срабатывал при ZF=0. ; Поэтому мы используем логику: if (ZF == 0) jmp; (псевдокод). ; Это можно выразить как: if (ZF == 1) goto skip_jmp; jmp target; skip_jmp: ... (псевдокод). ; Это и есть: cmp ...; je skip_jmp; jmp target; skip_jmp: ... ; Где 'jmp target' - это прыжок, который происходит, если ZF=0 (т.е. когда je НЕ сработал). ; Итак: ; cmp rax, rbx (ZF=0) ; je skip_jmp (ZF=0, переход НЕ сработает -> идем дальше) ; переход мимо_мертвого_кода_2 (ZF=0, СРАБОТАЕТ -> прыгаем мимо мертвого кода) ; skip_jmp: (ZF=1, мы сюда попали, прыгнув через безусловный переход) ; [мертвый код 2 - выполнится ТОЛЬКО если ZF=1] ; мимо_мертвого_кода_2: ; [продолжение] ; Это как раз то, что нужно! ; cmp rax, rbx (ZF=0) ; je skip_jmp (ZF=0 -> не прыгаем) ; переход мимо_мертвого_кода_2 (ZF=0 -> прыгаем мимо мертвого кода 2) ; skip_jmp: (ZF=1 -> сюда попали, прыгнув через безусловный переход) сравнить раикс, рбикс переход_если_равно skip_jmp переход мимо_мертвого_кода_2 skip_jmp: ; --- МЕРТВЫЙ КОД 2 --- ; Этот код НЕ должен выполниться (так как ZF=0) ; Добавляем "мусор", чтобы точно выйти за пределы короткого перехода переместить_имм раикс, 1 переместить_имм рдиай, 1 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 2 переместить_имм рдиай, 2 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 3 переместить_имм рдиай, 3 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 4 переместить_имм рдиай, 4 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 5 переместить_имм рдиай, 5 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 6 переместить_имм рдиай, 6 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 7 переместить_имм рдиай, 7 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 8 переместить_имм рдиай, 8 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 9 переместить_имм рдиай, 9 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 10 переместить_имм рдиай, 10 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 11 переместить_имм рдиай, 11 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 12 переместить_имм рдиай, 12 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 13 переместить_имм рдиай, 13 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 14 переместить_имм рдиай, 14 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы переместить_имм раикс, 15 переместить_имм рдиай, 15 переместить_имм рсиай, msg_dead_2 переместить_имм рдикс, len_msg_dead_2 вызов_системы ; --------------------- мимо_мертвого_кода_2: ; --- ВЫВОД ЦЕЛЕВОГО СООБЩЕНИЯ --- вывести_сообщение: переместить_имм раикс, 1 переместить_имм рдиай, 1 переместить_имм рсиай, msg_success переместить_имм рдикс, len_msg_success вызов_системы ; --- ЗАВЕРШЕНИЕ --- переместить_имм раикс, 60 переместить_имм рдиай, 0 вызов_системы .данные ; Перемешиваем строки и константы msg_success: .строка_нуль "Успех!\n" .константа len_msg_success = 12 ; msg_dead_2: .строка_нуль "Мертвый код 2!" .константа len_msg_dead_2 = 14 msg_dead_1: .строка_нуль "Мертвый код 1!" .константа len_msg_dead_1 = 14