kvs/short_jumps/шорт_тест.квс
2025-11-08 13:24:11 +03:00

238 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; шорт_тест.квс (обновлённый)
; Исходный файл для тестирования всех коротких условных переходов
.текст
.глобал _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