Commit 67b939f6 authored by Andrey Zhdanov's avatar Andrey Zhdanov
Browse files

update tests

parent 4a075896
# Assignment: Input/Output library in assembly
# Assignment 1: Input/Output library in assembly
---
Лабораторная работа: библиотека ввода-вывода на Assembler
Лабораторная работа 1: библиотека ввода-вывода на Assembler
Реализуйте библиотеку процедур, которые будут выполнять простые действия со строками, числами и их текстовыми представлениями.
......@@ -9,7 +9,7 @@
* Прочитайте первые две главы "Low-level programming: C, assembly and program execution".
* Ознакомьтесь с [документацией на следующие инструкции](https://gitlab.se.ifmo.ru/programming-languages/cse-programming-languages-fall-2021/main/-/blob/main/docs/intel-manual.pdf).
* Ознакомьтесь с [документацией на следующие инструкции](https://gitlab.se.ifmo.ru/programming-languages/cse-programming-languages-fall-2024/main/-/blob/main/docs/intel-manual.pdf) и [Документацией по Linux ABI](https://gitlab.se.ifmo.ru/programming-languages/cse-programming-languages-fall-2024/main/-/blob/main/docs/x86_64-abi-0.99.pdf).
- `xor`
- `jmp`, `ja` и другими командами условного перехода
......@@ -26,15 +26,14 @@
![](./img/outline.png)
* Прочитайте документацию на системный вызов `read` с помощью `man`. Его номер (который кладётся в `rax`) 0.
* Прочитайте документацию на системный вызов `read` с помощью `man`. Его номер (который кладётся в `rax`) 0. Информацию о регистрах, используемых для передачи параметров в системные вызовы можно найти в [таблице](https://gitlab.se.ifmo.ru/programming-languages/cse-programming-languages-fall-2024/main/-/blob/main/docs/system-calls.md).
# Написание
- Впишите в `lib.inc` код вместо заглушек функций. По возможности переиспользуйте уже реализованные функции.
- Впишите в `lib.asm` код вместо заглушек функций. По возможности переиспользуйте уже реализованные функции.
- Используйте `test.py` чтобы протестировать работу.
Скрипт `test.py` будет генерировать исполняемый файл с тестом для каждой функции, вы можете отладить его; также см. Appendix A в "Low-level programming: C, assembly and program execution".
Скрипт `test.py` будет генерировать набор исполняемых файлов с тестами для каждой функции, вы можете отладить их по-отделенности; также см. Appendix A в "Low-level programming: C, assembly and program execution". При выполнении тестов проверяется соответствие кода соглашениям о вызовах и выравнивание стека кратно 16 перед всеми вызовами `call`.
# Список распространённых ошибок
......@@ -49,7 +48,8 @@
- Проверьте, что `parse_int` и `parse_uint` корректно устанавливают `rdx` (очень важно для следующего задания)
- Проверьте, что функции `parse_int`, `parse_uint` и `read_word` правильно работают когда ввод завершается с помощью `Ctrl-D`.
- При использовании стека надо не забывать уменшать `rsp`.
- Перед каждым вызовом `call` необходимо выравнивать стек кратно 16.
- Вызовы `syscall` могут изменить значения регистров `rax`, `rcx` и `r11`.
- Обратные кавычки позволяют использовать специальные символы в С-стиле (`\n`, `\t`).
Код решения занимает порядка 250 строк.
section .text
; Принимает код возврата и завершает текущий процесс
exit:
xor rax, rax,
ret
; Принимает указатель на нуль-терминированную строку, возвращает её длину
string_length:
xor rax, rax
ret
; Принимает указатель на нуль-терминированную строку, выводит её в stdout
print_string:
xor rax, rax
ret
; Принимает код символа и выводит его в stdout
print_char:
xor rax, rax
ret
; Переводит строку (выводит символ с кодом 0xA)
print_newline:
xor rax, rax
ret
; Выводит беззнаковое 8-байтовое число в десятичном формате
; Совет: выделите место в стеке и храните там результаты деления
; Не забудьте перевести цифры в их ASCII коды.
print_uint:
xor rax, rax
ret
; Выводит знаковое 8-байтовое число в десятичном формате
print_int:
xor rax, rax
ret
; Принимает два указателя на нуль-терминированные строки, возвращает 1 если они равны, 0 иначе
string_equals:
xor rax, rax
ret
; Читает один символ из stdin и возвращает его. Возвращает 0 если достигнут конец потока
read_char:
xor rax, rax
ret
; Принимает: адрес начала буфера, размер буфера
; Читает в буфер слово из stdin, пропуская пробельные символы в начале, .
; Пробельные символы это пробел 0x20, табуляция 0x9 и перевод строки 0xA.
; Останавливается и возвращает 0 если слово слишком большое для буфера
; При успехе возвращает адрес буфера в rax, длину слова в rdx.
; При неудаче возвращает 0 в rax
; Эта функция должна дописывать к слову нуль-терминатор
read_word:
ret
; Принимает указатель на строку, пытается
; прочитать из её начала беззнаковое число.
; Возвращает в rax: число, rdx : его длину в символах
; rdx = 0 если число прочитать не удалось
parse_uint:
xor rax, rax
ret
; Принимает указатель на строку, пытается
; прочитать из её начала знаковое число.
; Если есть знак, пробелы между ним и числом не разрешены.
; Возвращает в rax: число, rdx : его длину в символах (включая знак, если он был)
; rdx = 0 если число прочитать не удалось
parse_int:
xor rax, rax
ret
; Принимает указатель на строку, указатель на буфер и длину буфера
; Копирует строку в буфер
; Возвращает длину строки если она умещается в буфер, иначе 0
string_copy:
xor rax, rax
ret
......@@ -41,6 +41,10 @@ def first_or_empty( s ):
before_all="""
%macro call 1
mov rax, rsp
and rax, 15
test rax, rax
jz alignment_error
mov rax, -1
push rbx
push rbp
......@@ -76,11 +80,21 @@ mov r10, -1
mov r11, -1
%endmacro
%include "lib.inc"
%include "lib.asm"
global _start
section .text
alignment_error:
mov rax, 1
mov rdi, 2
mov rsi, err_alignment_error
mov rdx, err_alignment_error.end - err_alignment_error
syscall
mov rax, 60
mov rdi, -41
syscall
convention_error:
mov rax, 1
mov rdi, 2
......@@ -92,6 +106,8 @@ convention_error:
syscall
section .data
err_alignment_error: db "You did not respect the calling convention! Check that you align stack before call correctly", 10
.end:
err_calling_convention: db "You did not respect the calling convention! Check that you handled caller-saved and callee-saved registers correctly", 10
.end:
"""
......@@ -132,7 +148,9 @@ str: db '""" + input + """', 0
section .text
_start:
mov rdi, str
sub rsp, 8
call string_length
add rsp, 8
mov rdi, rax
mov rax, 60
syscall
......@@ -151,8 +169,10 @@ str: db '""" + input + """', 0
section .text
_start:
sub rsp, 8
mov rdi, str
call print_string
add rsp, 8
xor rdi, rdi
mov rax, 60
syscall
......@@ -172,13 +192,14 @@ arg2: times """ + str(len(input) + 1) + """ db 66
section .text
_start:
sub rsp, 8
mov rdi, arg1
mov rsi, arg2
mov rdx, """ + str(len(input) + 1) + """
call string_copy
mov rdi, arg2
call print_string
add rsp, 8
mov rax, 60
xor rdi, rdi
syscall
......@@ -201,6 +222,7 @@ arg2: times """ + str(len(input)//2) + """ db 66
section .text
_start:
sub rsp, 8
mov rdi, arg1
mov rsi, arg2
mov rdx, """ + str(len(input)//2) + """
......@@ -214,6 +236,7 @@ _start:
mov rdi, arg2
call print_string
_exit:
add rsp, 8
mov rax, 60
xor rdi, rdi
syscall
......@@ -229,8 +252,10 @@ _exit:
text = """
section .text
_start:
sub rsp, 8
mov rdi, '""" + input + """'
call print_char
add rsp, 8
mov rax, 60
xor rdi, rdi
syscall
......@@ -246,8 +271,10 @@ _start:
text = """
section .text
_start:
sub rsp, 8
mov rdi, """ + input + """
call print_uint
add rsp, 8
mov rax, 60
xor rdi, rdi
syscall
......@@ -264,8 +291,10 @@ _start:
text = """
section .text
_start:
sub rsp, 8
mov rdi, """ + input + """
call print_int
add rsp, 8
mov rax, 60
xor rdi, rdi
syscall
......@@ -281,7 +310,9 @@ _start:
text = """
section .text
_start:
sub rsp, 8
call read_char
add rsp, 8
mov rdi, rax
mov rax, 60
syscall
......@@ -304,12 +335,13 @@ word_buf: times 20 db 0xca
section .text
_start:
sub rsp, 8
mov rdi, word_buf
mov rsi, 20
call read_word
mov rdi, rax
call print_string
add rsp, 8
mov rax, 60
xor rdi, rdi
syscall
......@@ -329,9 +361,11 @@ word_buf: times 20 db 0xca
section .text
_start:
sub rsp, 8
mov rdi, word_buf
mov rsi, 20
call read_word
add rsp, 8
mov rax, 60
mov rdi, rdx
syscall
......@@ -352,9 +386,11 @@ word_buf: times 20 db 0xca
section .text
_start:
sub rsp, 8
mov rdi, word_buf
mov rsi, 20
call read_word
add rsp, 8
mov rdi, rax
mov rax, 60
syscall
......@@ -377,11 +413,14 @@ input: db '""" + input + """', 0
section .text
_start:
sub rsp, 8
mov rdi, input
call parse_uint
add rsp, 8
push rdx
mov rdi, rax
call print_uint
add rsp, 8
mov rax, 60
pop rdi
syscall
......@@ -403,11 +442,14 @@ input: db '""" + input + """', 0
section .text
_start:
sub rsp, 8
mov rdi, input
call parse_int
add rsp, 8
push rdx
mov rdi, rax
call print_int
add rsp, 8
mov rax, 60
pop rdi
syscall
......@@ -433,9 +475,11 @@ str2: db '""" + input + """',0
section .text
_start:
sub rsp, 8
mov rdi, str1
mov rsi, str2
call string_equals
add rsp, 8
mov rdi, rax
mov rax, 60
syscall
......@@ -455,9 +499,11 @@ str2: db '""" + input + """!!',0
section .text
_start:
sub rsp, 8
mov rdi, str1
mov rsi, str2
call string_equals
add rsp, 8
mov rdi, rax
mov rax, 60
syscall
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment