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