From f1f602c617eb0375bcfdda6696f962aa496f002d Mon Sep 17 00:00:00 2001 From: mzhoot Date: Sun, 28 Jun 2026 12:06:14 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20=D0=BC=D0=BD?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=D0=B7=D0=BD=D0=B0=D1=87=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D1=87=D0=B8=D1=81=D0=BB=D0=B0=20=D0=B2=20=D1=82=D0=B5?= =?UTF-8?q?=D1=80=D0=BC=D0=B8=D0=BD=D0=B0=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- тесты/kvs_full_test.csv | 3 +- .../вывод_многозначного.py | 103 ++++++++++++++++++ ...ывод_многозначного.квс | 81 ++++++++++++++ ...вывод_однозначного.квс | 1 + 4 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 тесты/вывод_многозначного/вывод_многозначного.py create mode 100644 тесты/вывод_многозначного/вывод_многозначного.квс diff --git a/тесты/kvs_full_test.csv b/тесты/kvs_full_test.csv index ccb7d01..f1bb4a3 100644 --- a/тесты/kvs_full_test.csv +++ b/тесты/kvs_full_test.csv @@ -24,4 +24,5 @@ 1;тест_адресации_р12;Проверка косвенной адресации через R12 (ASCII код первого символа аргумента) 1;вызов_функции;Проверка вызова функций и возврата: сложение 10+20=30 через код возврата 1;остаток_от_деления;Проверка деления и получения остатка: 42 % 10 = 2 (проверка через код возврата) -1;вывод_однозначного;Проверка вывода однозначного числа: цифра 7 → символ '7' через write \ No newline at end of file +1;вывод_однозначного;Проверка вывода однозначного числа: цифра 7 → символ '7' через write +1;вывод_многозначного;Проверка вывода многозначного числа: 12345 → "12345" через деление, стек и циклы \ No newline at end of file diff --git a/тесты/вывод_многозначного/вывод_многозначного.py b/тесты/вывод_многозначного/вывод_многозначного.py new file mode 100644 index 0000000..d37311c --- /dev/null +++ b/тесты/вывод_многозначного/вывод_многозначного.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Тест для проверки вывода многозначного числа +Преобразует число 12345 в строку через деление на 10 и стек +Ожидаемый вывод: "12345" +""" + +import subprocess +import sys +import os +from pathlib import Path + +# Определяем пути +SCRIPT_DIR = Path(__file__).parent.absolute() +PROJECT_ROOT = SCRIPT_DIR.parent.parent +SOURCE_REL = SCRIPT_DIR / "вывод_многозначного.квс" + +def clean(): + """Очищает артефакты сборки""" + files = [ + "вывод_многозначного.elf", + "вывод_многозначного.csv", + "вывод_многозначного.аст", + "вывод_многозначного.токены", + "вывод_многозначного.константа", + "вывод_многозначного_pass4.log" + ] + for f in files: + f_path = SCRIPT_DIR / f + if f_path.exists(): + f_path.unlink() + print(f"DEBUG: Удалён {f}", file=sys.stderr) + +def build() -> bool: + """Собирает тестовую программу с помощью КВС""" + print(f"DEBUG: Сборка {SOURCE_REL}", file=sys.stderr) + os.chdir(PROJECT_ROOT) + + build = subprocess.run( + ["python3", "квс_сборка.py", str(SOURCE_REL)], + capture_output=True, + text=True + ) + + if build.returncode != 0: + print(f"❌ Ошибка сборки: {build.returncode}", file=sys.stderr) + print(build.stderr, file=sys.stderr) + return False + + print("DEBUG: Сборка успешна", file=sys.stderr) + return True + +def test_output() -> bool: + """Запускает программу и проверяет вывод""" + print("DEBUG: Запуск ELF, ожидается вывод '12345'", file=sys.stderr) + os.chdir(SCRIPT_DIR) + + elf_path = SCRIPT_DIR / "вывод_многозначного.elf" + if not elf_path.exists(): + print("❌ ELF файл не найден", file=sys.stderr) + return False + + run = subprocess.run( + [str(elf_path)], + capture_output=True, + text=True + ) + + expected_output = "12345" + + if run.stdout != expected_output: + print(f"❌ Вывод не совпадает", file=sys.stderr) + print(f" Ожидалось: {repr(expected_output)}", file=sys.stderr) + print(f" Получено: {repr(run.stdout)}", file=sys.stderr) + return False + + if run.returncode != 0: + print(f"❌ Код возврата: ожидался 0, получен {run.returncode}", file=sys.stderr) + return False + + print(f"DEBUG: Тест пройден (вывод '{run.stdout}', код {run.returncode})", file=sys.stderr) + return True + +def main(): + """Главная функция теста""" + print("DEBUG: Начало теста вывод_многозначного", file=sys.stderr) + + if not build(): + clean() + sys.exit(1) + + if not test_output(): + clean() + sys.exit(1) + + clean() + print("✅ Все тесты пройдены!", file=sys.stderr) + sys.exit(0) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/тесты/вывод_многозначного/вывод_многозначного.квс b/тесты/вывод_многозначного/вывод_многозначного.квс new file mode 100644 index 0000000..9c3802f --- /dev/null +++ b/тесты/вывод_многозначного/вывод_многозначного.квс @@ -0,0 +1,81 @@ +;./тесты/вывод_многозначного/вывод_многозначного.elf +; Ожидаемый вывод: "12345" + +; ============================================================ +; вывод_многозначного.квс - вывод многозначного числа +; Преобразует число 12345 в строку через деление на 10 и стек +; ============================================================ + +.текст +.глобал _start + +_start: + ; Загружаем число для вывода + переместить_имм раикс, 12345 ; число для преобразования + + ; Счётчик цифр = 0 + переместить_имм р8, 0 ; счётчик цифр в R8 + +цикл_деления: + ; Проверяем, не ноль ли остался + сравнить_с раикс, 0 + переход_если_равно вывод_цифр ; если 0 — всё, выводим + + ; Обнуляем RDX перед делением (старшая часть делимого) + переместить_имм рдикс, 0 + + ; Делим на 10: RAX = частное, RDX = остаток + переместить_имм рбикс, 10 + разделить рбикс ; RAX/RBX → RAX(частное), RDX(остаток) + + ; Преобразуем остаток в ASCII: остаток + '0' + прибавить_непосредственно рдикс, 48 ; RDX = цифра + 48 = ASCII-код + + ; Сохраняем цифру в стеке + втолкнуть рдикс + + ; Увеличиваем счётчик + увеличить р8 + + ; Продолжаем цикл (RAX уже содержит частное) + короткий_переход цикл_деления + +вывод_цифр: + ; Теперь в стеке цифры в обратном порядке, счётчик в R8 + ; Указатель на буфер в R9 + переместить_имм р9, буфер + +цикл_вывода: + ; Проверяем, все ли цифры вытащили + сравнить_с р8, 0 + переход_если_равно готово + + ; Достаём цифру из стека + вытолкнуть раикс + + ; Записываем байт в буфер + сохранить [р9], ал + + ; Сдвигаем указатель буфера + увеличить р9 + + ; Уменьшаем счётчик + уменьшить р8 + + короткий_переход цикл_вывода + +готово: + ; Системный вызов write(1, буфер, длина) + переместить_имм раикс, 1 ; номер syscall write = 1 + переместить_имм рдиай, 1 ; stdout = 1 + переместить_имм рсиай, буфер ; указатель на буфер + переместить_имм рдикс, 5 ; длина = 5 (для 12345) + вызов_системы + + ; Системный вызов exit(0) + переместить_имм раикс, 60 ; номер syscall exit = 60 + переместить_имм рдиай, 0 ; код возврата = 0 + вызов_системы + +.данные +буфер: .байт 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 10 байт с запасом \ No newline at end of file diff --git a/тесты/вывод_однозначного/вывод_однозначного.квс b/тесты/вывод_однозначного/вывод_однозначного.квс index b2d613a..724ec8a 100644 --- a/тесты/вывод_однозначного/вывод_однозначного.квс +++ b/тесты/вывод_однозначного/вывод_однозначного.квс @@ -4,6 +4,7 @@ ; ============================================================ ; вывод_однозначного.квс - вывод однозначного числа без циклов ; Преобразует цифру 7 в символ '7' через сложение с '0' +; и выводит в терминал ; ============================================================ .текст