; шорт_тест.квс (обновлённый) ; Исходный файл для тестирования всех коротких условных переходов .текст .глобал _start _start: ; Подготовка: инициализируем регистры для тестирования флагов переместить_имм раикс, 5 ; rax = 5 переместить_имм рбикс, 3 ; rbx = 3 переместить_имм рсикс, 5 ; rcx = 5 (для теста равенства) ; --- Тесты для переходов, зависящих от результата cmp --- ; cmp rax, rbx -> rax(5) > rbx(3) -> SF != OF, ZF = 0 сравнить раикс, рбикс ; Переход если равно (ZF=1) -> не сработает, прыгаем мимо короткий_переход_если_равно мимо_равно переместить_имм рдикс, 1 ; Если сюда попали, ZF=0 переместить_имм рсиай, msg_zf_clear переместить_имм рдикс, len_msg_zf_clear переместить_имм раикс, 1 ; write переместить_имм рдиай, 1 ; stdout вызов_системы короткий_переход мимо_равно мимо_равно: ; Переход если не равно (ZF=0) -> сработает короткий_переход_если_не_ноль мимо_не_равно переместить_имм рдикс, 1 ; Не должно сработать переместить_имм рсиай, msg_should_not_print переместить_имм рдикс, len_msg_should_not_print переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы мимо_не_равно: ; Переход если меньше (SF != OF и SF=1) -> не сработает (SF=0, OF=0) короткий_переход_если_меньше мимо_меньше переместить_имм рдикс, 1 ; SF=0 переместить_имм рсиай, msg_sf_clear переместить_имм рдикс, len_msg_sf_clear переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы короткий_переход после_меньше мимо_меньше: ; Если сработал переход, то SF=1 переместить_имм рдикс, 1 переместить_имм рсиай, msg_sf_set переместить_имм рдикс, len_msg_sf_set переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы после_меньше: ; Переход если больше (ZF=0 и SF=OF) -> сработает (ZF=0, SF=0, OF=0) короткий_переход_если_больше после_больше ; Если сюда попали, условие не выполнилось переместить_имм рдикс, 1 переместить_имм рсиай, msg_should_not_print переместить_имм рдикс, len_msg_should_not_print переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы короткий_переход после_еще_одного после_больше: ; Переход если меньше или равно (ZF=1 или SF!=OF) -> не сработает (ZF=0, SF=OF=0) короткий_переход_если_меньше_или_равно мимо_меньше_равно ; Условие не выполнилось, ZF=0, SF=OF переместить_имм рдикс, 1 переместить_имм рсиай, msg_zf_clear_or_sf_eq_of переместить_имм рдикс, len_msg_zf_clear_or_sf_eq_of переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы короткий_переход после_еще_одного мимо_меньше_равно: ; Условие выполнилось, ZF=1 или SF!=OF переместить_имм рдикс, 1 переместить_имм рсиай, msg_zf_set_or_sf_neq_of переместить_имм рдикс, len_msg_zf_set_or_sf_neq_of переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы после_еще_одного: ; Переход если больше или равно (SF=OF) -> сработает (SF=0, OF=0) короткий_переход_если_больше_или_равно после_больше_равно ; Условие не выполнилось, SF != OF переместить_имм рдикс, 1 переместить_имм рсиай, msg_sf_neq_of переместить_имм рдикс, len_msg_sf_neq_of переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы короткий_переход конец_cmp после_больше_равно: ; Условие выполнилось, SF = OF переместить_имм рдикс, 1 переместить_имм рсиай, msg_sf_eq_of переместить_имм рдикс, len_msg_sf_eq_of переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы конец_cmp: ; --- Тесты для переходов, зависящих от флага переноса (CF) --- ; Проверим CF, установив его с помощью вычитания ; rax = 3, rbx = 5 -> rax - rbx -> CF=1 (т.к. 3 < 5) переместить_имм раикс, 3 переместить_имм рбикс, 5 вычесть рбикс, раикс ; rax = rax - rbx, CF=1 ; Переход если перенос (CF=1) -> сработает короткий_переход_если_перенос после_cf_set ; Это не должно напечататься переместить_имм рдикс, 1 переместить_имм рсиай, msg_should_not_print переместить_имм рдикс, len_msg_should_not_print переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы короткий_переход после_cf_clear после_cf_set: ; CF был установлен переместить_имм рдикс, 1 переместить_имм рсиай, msg_cf_set переместить_имм рдикс, len_msg_cf_set переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы ; Теперь очистим CF, например, через сравнение 5 и 3 переместить_имм раикс, 5 переместить_имм рбикс, 3 сравнить раикс, рбикс ; rax - rbx, CF=0 (т.к. 5 >= 3) ; Переход если нет переноса (CF=0) -> сработает после_cf_clear: короткий_переход_если_нет_переноса после_cf_tests ; Это не должно напечататься переместить_имм рдикс, 1 переместить_имм рсиай, msg_should_not_print переместить_имм рдикс, len_msg_should_not_print переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы короткий_переход после_cf_tests после_cf_tests: ; CF был очищен переместить_имм рдикс, 1 переместить_имм рсиай, msg_cf_clear переместить_имм рдикс, len_msg_cf_clear переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы ; --- Тесты для переходов, зависящих от ZF (через test) --- ; test rax, rax -> ZF=0 (rax != 0) переместить_имм раикс, 10 проверить раикс, раикс ; Переход если ноль (ZF=1) -> не сработает короткий_переход_если_ноль мимо_test_zf ; ZF=0 переместить_имм рдикс, 1 переместить_имм рсиай, msg_zf_clear переместить_имм рдикс, len_msg_zf_clear переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы короткий_переход после_test_zf мимо_test_zf: ; ZF=1 переместить_имм рдикс, 1 переместить_имм рсиай, msg_zf_set переместить_имм рдикс, len_msg_zf_set переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы после_test_zf: ; test rax, rax -> ZF=1 (rax = 0) переместить_имм раикс, 0 проверить раикс, раикс ; Переход если ноль (ZF=1) -> сработает короткий_переход_если_ноль после_test_zf2 ; Это не должно напечататься переместить_имм рдикс, 1 переместить_имм рсиай, msg_should_not_print переместить_имм рдикс, len_msg_should_not_print переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы короткий_переход после_test_zf2 после_test_zf2: ; ZF=1 переместить_имм рдикс, 1 переместить_имм рсиай, msg_zf_set переместить_имм рдикс, len_msg_zf_set переместить_имм раикс, 1 переместить_имм рдиай, 1 вызов_системы ; --- Завершение --- переместить_имм раикс, 60 ; exit переместить_имм рдиай, 0 ; status вызов_системы .данные msg_zf_clear: .строка_нуль "ZF=0 (Clear). " .константа len_msg_zf_clear = 15 msg_zf_set: .строка_нуль "ZF=1 (Set). " .константа len_msg_zf_set = 12 msg_sf_clear: .строка_нуль "SF=0 (Clear). " .константа len_msg_sf_clear = 14 msg_sf_set: .строка_нуль "SF=1 (Set). " .константа len_msg_sf_set = 12 msg_sf_eq_of: .строка_нуль "SF=OF. " .константа len_msg_sf_eq_of = 8 msg_sf_neq_of: .строка_нуль "SF!=OF. " .константа len_msg_sf_neq_of = 8 msg_zf_clear_or_sf_eq_of: .строка_нуль "ZF=0 или SF=OF. " .константа len_msg_zf_clear_or_sf_eq_of = 16 msg_zf_set_or_sf_neq_of: .строка_нуль "ZF=1 или SF!=OF. " .константа len_msg_zf_set_or_sf_neq_of = 16 msg_cf_set: .строка_нуль "CF=1 (Carry Set). " .константа len_msg_cf_set = 18 msg_cf_clear: .строка_нуль "CF=0 (No Carry). " .константа len_msg_cf_clear = 17 msg_should_not_print: .строка_нуль "ОШИБКА: Это не должно быть напечатано! " .константа len_msg_should_not_print = 36