тест остатк от деления на 10
This commit is contained in:
parent
309bbd460a
commit
70ed97cec6
|
|
@ -22,4 +22,5 @@
|
||||||
1;тест_адресации_р15;Проверка косвенной адресации через R15 (ASCII код первого символа аргумента)
|
1;тест_адресации_р15;Проверка косвенной адресации через R15 (ASCII код первого символа аргумента)
|
||||||
1;двоеточие_в_строке;Проверка обработки строк с двоеточием внутри
|
1;двоеточие_в_строке;Проверка обработки строк с двоеточием внутри
|
||||||
1;тест_адресации_р12;Проверка косвенной адресации через R12 (ASCII код первого символа аргумента)
|
1;тест_адресации_р12;Проверка косвенной адресации через R12 (ASCII код первого символа аргумента)
|
||||||
1;вызов_функции;Проверка вызова функций и возврата: сложение 10+20=30 через код возврата
|
1;вызов_функции;Проверка вызова функций и возврата: сложение 10+20=30 через код возврата
|
||||||
|
1;остаток_от_деления;Проверка деления и получения остатка: 42 % 10 = 2 (проверка через код возврата)
|
||||||
|
Can't render this file because it contains an unexpected character in line 2 and column 46.
|
117
тесты/остаток_от_деления/остаток_от_деления.py
Normal file
117
тесты/остаток_от_деления/остаток_от_деления.py
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Тест для проверки операции деления и получения остатка
|
||||||
|
Запускает скомпилированную программу и проверяет код возврата
|
||||||
|
Ожидаемый результат: 42 % 10 = 2
|
||||||
|
"""
|
||||||
|
|
||||||
|
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:
|
||||||
|
"""
|
||||||
|
Собирает тестовую программу с помощью КВС
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True если сборка успешна, иначе False
|
||||||
|
"""
|
||||||
|
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_division_remainder() -> bool:
|
||||||
|
"""
|
||||||
|
Запускает скомпилированную программу и проверяет код возврата
|
||||||
|
42 % 10 = 2
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True если код возврата = 2, иначе False
|
||||||
|
"""
|
||||||
|
print("DEBUG: Запуск ELF, ожидается код возврата 2", 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_code = 2 # 42 % 10 = 2
|
||||||
|
|
||||||
|
if run.returncode != expected_code:
|
||||||
|
print(f"❌ Код возврата: ожидался {expected_code}, получен {run.returncode}", file=sys.stderr)
|
||||||
|
if run.stderr:
|
||||||
|
print(f" stderr: {run.stderr}", file=sys.stderr)
|
||||||
|
if run.stdout:
|
||||||
|
print(f" stdout: {run.stdout}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"DEBUG: Тест пройден (код {run.returncode})", file=sys.stderr)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Главная функция теста"""
|
||||||
|
print("DEBUG: Начало теста остаток_от_деления", file=sys.stderr)
|
||||||
|
|
||||||
|
# Собираем программу
|
||||||
|
if not build():
|
||||||
|
clean()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Запускаем тест
|
||||||
|
if not test_division_remainder():
|
||||||
|
clean()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Очищаем артефакты
|
||||||
|
clean()
|
||||||
|
|
||||||
|
print("✅ Все тесты пройдены!", file=sys.stderr)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
35
тесты/остаток_от_деления/остаток_от_деления.квс
Normal file
35
тесты/остаток_от_деления/остаток_от_деления.квс
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
;./тесты/остаток_от_деления/остаток_от_деления.elf
|
||||||
|
;echo $? # должен быть 2
|
||||||
|
|
||||||
|
;для вывода чисел в терминал нужно преобразование в строку
|
||||||
|
;а для этого нужен остаток от деления (но тут надо бы больше случаев отработать)
|
||||||
|
|
||||||
|
; ============================================================
|
||||||
|
; остаток_от_деления.квс - тест операции деления и остатка
|
||||||
|
; Проверяем: 42 / 10 = 4 остаток 2
|
||||||
|
; ============================================================
|
||||||
|
|
||||||
|
.текст
|
||||||
|
.глобал _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
; Подготовка делимого: RDX:RAX = 0:42
|
||||||
|
переместить_имм раикс, 42 ; делимое = 42
|
||||||
|
переместить_имм рдикс, 0 ; обнуляем RDX (старшая часть 128-битного делимого)
|
||||||
|
|
||||||
|
; Делитель в регистр
|
||||||
|
переместить_имм рбикс, 10 ; делитель = 10
|
||||||
|
|
||||||
|
; Выполняем деление: RDX:RAX / RBX
|
||||||
|
; После деления: RAX = частное (4), RDX = остаток (2)
|
||||||
|
разделить рбикс
|
||||||
|
|
||||||
|
; Перемещаем остаток в RDI для кода возврата
|
||||||
|
переместить рдиай, рдикс ; остаток из RDX в RDI
|
||||||
|
|
||||||
|
; Системный вызов exit
|
||||||
|
переместить_имм раикс, 60 ; номер syscall exit = 60
|
||||||
|
вызов_системы
|
||||||
|
|
||||||
|
.данные
|
||||||
|
тестовая_переменная: .байт 0
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
; Файл: черновик/черновик.квс
|
|
||||||
; Тест операции сложения (прибавить)
|
; Тест операции сложения (прибавить)
|
||||||
; Результат должен быть 42
|
; Результат должен быть 42
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,148 @@
|
||||||
|
; ============================================================
|
||||||
|
; вывод_числа.квс — исправленный синтаксис деления
|
||||||
|
; ============================================================
|
||||||
|
|
||||||
.текст
|
.текст
|
||||||
.глобал _start
|
.глобал _start
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
; Вызов функции с двумя аргументами
|
переместить_имм раикс, -12345
|
||||||
переместить_имм рдиай, 10 ; первый аргумент = 10
|
вызвать вывести_число
|
||||||
переместить_имм рсиай, 20 ; второй аргумент = 20
|
|
||||||
вызвать сложить_два_числа
|
|
||||||
|
|
||||||
; Результат в RAX — используем как код возврата
|
; Вывод перевода строки
|
||||||
переместить рдиай, раикс ; первый аргумент sys_exit = результат
|
переместить_имм раикс, 1
|
||||||
переместить_имм раикс, 60 ; sys_exit
|
переместить_имм рдиай, 1
|
||||||
|
переместить_имм рсиай, новая_строка
|
||||||
|
переместить_имм рдикс, 1
|
||||||
|
вызов_системы
|
||||||
|
|
||||||
|
; Завершение
|
||||||
|
переместить_имм раикс, 60
|
||||||
|
переместить_имм рдиай, 0
|
||||||
вызов_системы
|
вызов_системы
|
||||||
|
|
||||||
сложить_два_числа:
|
вывести_число:
|
||||||
; Пролог
|
|
||||||
втолкнуть рбипи
|
втолкнуть рбипи
|
||||||
переместить рбипи, рсипи
|
переместить рбипи, рсипи
|
||||||
|
|
||||||
; Тело функции: сложить аргументы
|
втолкнуть рбикс
|
||||||
прибавить рдиай, рсиай ; RDI += RSI
|
втолкнуть рсикс
|
||||||
переместить раикс, рдиай ; результат в RAX
|
втолкнуть рдикс
|
||||||
|
втолкнуть р8
|
||||||
|
втолкнуть р9
|
||||||
|
втолкнуть р10
|
||||||
|
втолкнуть р11
|
||||||
|
|
||||||
|
; ---- Проверка на отрицательное ----
|
||||||
|
проверить раикс, раикс
|
||||||
|
переход_если_больше_или_равно _положительное
|
||||||
|
|
||||||
|
втолкнуть раикс
|
||||||
|
переместить_имм раикс, 1
|
||||||
|
переместить_имм рдиай, 1
|
||||||
|
переместить_имм рсиай, минус_символ
|
||||||
|
переместить_имм рдикс, 1
|
||||||
|
вызов_системы
|
||||||
|
вытолкнуть раикс
|
||||||
|
отрицать раикс
|
||||||
|
|
||||||
|
_положительное:
|
||||||
|
; ---- Сохраняем число в R8 ----
|
||||||
|
переместить р8, раикс
|
||||||
|
переместить_имм р9, 0
|
||||||
|
|
||||||
|
; ---- Устанавливаем R10 на КОНЕЦ буфера (буфер + 19) ----
|
||||||
|
переместить_имм р10, буфер
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
увеличить р10
|
||||||
|
|
||||||
|
; Записываем нуль-терминатор
|
||||||
|
переместить_имм [р10], 0
|
||||||
|
|
||||||
|
; ---- Особый случай: число = 0 ----
|
||||||
|
проверить р8, р8
|
||||||
|
переход_если_равно _ноль_особый_случай
|
||||||
|
|
||||||
|
_цикл_деления:
|
||||||
|
проверить р8, р8
|
||||||
|
переход_если_равно _вывод_числа
|
||||||
|
|
||||||
|
; ---- ДЕЛЕНИЕ (исправленный синтаксис) ----
|
||||||
|
переместить_имм рдиай, 0 ; RDX = 0
|
||||||
|
переместить раикс, р8 ; RAX = R8
|
||||||
|
переместить_имм рсиай, 10 ; RSI = 10
|
||||||
|
разделить рдиай, раикс, рсиай ; ← ИСПРАВЛЕНО!
|
||||||
|
|
||||||
|
; ---- Сохраняем результат ----
|
||||||
|
переместить р8, раикс ; R8 = частное
|
||||||
|
прибавить рдиай, '0' ; RDX = цифра + '0'
|
||||||
|
уменьшить р10 ; двигаем указатель влево
|
||||||
|
сохранить [р10], дил ; сохраняем байт
|
||||||
|
увеличить р9 ; счётчик цифр++
|
||||||
|
переход _цикл_деления
|
||||||
|
|
||||||
|
_ноль_особый_случай:
|
||||||
|
; Если число = 0, записываем '0' в начало буфера
|
||||||
|
переместить_имм [буфер], '0'
|
||||||
|
переместить_имм р10, буфер
|
||||||
|
переместить_имм р9, 1
|
||||||
|
переход _вывод_числа
|
||||||
|
|
||||||
|
_вывод_числа:
|
||||||
|
переместить рсиай, р10
|
||||||
|
переместить рдикс, р9
|
||||||
|
вызвать вывести_строку
|
||||||
|
|
||||||
|
вытолкнуть р11
|
||||||
|
вытолкнуть р10
|
||||||
|
вытолкнуть р9
|
||||||
|
вытолкнуть р8
|
||||||
|
вытолкнуть рдикс
|
||||||
|
вытолкнуть рсикс
|
||||||
|
вытолкнуть рбикс
|
||||||
|
|
||||||
|
переместить рсипи, рбипи
|
||||||
|
вытолкнуть рбипи
|
||||||
|
вернуться
|
||||||
|
|
||||||
|
вывести_строку:
|
||||||
|
втолкнуть рбипи
|
||||||
|
переместить рбипи, рсипи
|
||||||
|
|
||||||
|
втолкнуть раикс
|
||||||
|
втолкнуть рдиай
|
||||||
|
|
||||||
|
переместить_имм раикс, 1
|
||||||
|
переместить_имм рдиай, 1
|
||||||
|
вызов_системы
|
||||||
|
|
||||||
|
вытолкнуть рдиай
|
||||||
|
вытолкнуть раикс
|
||||||
|
|
||||||
; Эпилог
|
|
||||||
переместить рсипи, рбипи
|
переместить рсипи, рбипи
|
||||||
вытолкнуть рбипи
|
вытолкнуть рбипи
|
||||||
вернуться
|
вернуться
|
||||||
|
|
||||||
.данные
|
.данные
|
||||||
тестовая_переменная: .байт 0
|
минус_символ: .байт '-'
|
||||||
|
новая_строка: .байт 10
|
||||||
|
|
||||||
|
.бнд
|
||||||
|
буфер: .резб 20
|
||||||
Loading…
Reference in a new issue