From 51e220410a29b0ef93841bed01655da348423f17 Mon Sep 17 00:00:00 2001 From: Miheev Egor Date: Sun, 22 Sep 2024 17:55:49 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=BD=D0=B5=D1=81=D0=BA=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=BA=D0=BE=20=D0=BF=D0=BE=D0=BB=D0=B5=D0=B7=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B9=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=204=20?= =?UTF-8?q?=D0=BF=D1=83=D0=BD=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03-asm-bios/task4.asm | 121 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 03-asm-bios/task4.asm diff --git a/03-asm-bios/task4.asm b/03-asm-bios/task4.asm new file mode 100644 index 0000000..a644e7a --- /dev/null +++ b/03-asm-bios/task4.asm @@ -0,0 +1,121 @@ +global _start + +%define STDIN 0 +%define STDOUT 1 +%define STDERR 2 + +section .data + src db 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 + src_size equ $-src + + ; резервируем 1 килобайт для буффера ввода и вывода + ; также в отдельной переменной сохраняем размер этого буфера + print_buf: times 1024 db 0 + buf_size equ $-print_buf + input_buf: times 1024 db 0 ; буфер, в который будет читаться символ со стандартного ввода + input_size equ $-src + + ; Для poll + %define POLLIN 0x001 ; Есть ли что почитать с буфера ввода. Понадобится для продолжения ввода + input_pollfd: + dd STDIN + dw POLLIN + dw 0 + +section .text + +%macro DIGIT_TO_ASCII 1 ; макрос, принимающий один аргумент (регистр или память) + add %1, '0' +%endmacro + +%macro ASCII_TO_DIGIT 1 ; макрос, принимающий один аргумент (регистр или память) + sub %1, '0' +%endmacro + +%macro PUSH_M 1-* ; push many; пушит в порядке следования + %rep %0 + push %1 + %rotate 1 + %endrep +%endmacro + +%macro POP_M 1-* ; pop many. читает в порядке следования + %rep %0 + pop %1 + %rotate 1 + %endrep +%endmacro + +%macro RPOP_M 1-* ; pop many. читает в обратном порядке + %rotate -1 + %rep %0 + pop %1 + %rotate -1 + %endrep +%endmacro + +; Передачу аргументов будем делать при помощи ABI - стандартная практика для linux +; Аргументы передаются в следующем порядке: rdi, rsi, rdx, rcx, r8, r9. Все, что не влезло, пушится в стек +; У передачи через стек тоже есть особенности, но их мы пока касаться не будем + +clean_print_buf: ; none -> void + PUSH_M rax, rcx, rdi + mov rcx, buf_size + mov rdi, print_buf + xor rax, rax ; будем заносить нули во всю память + rep stosb + RPOP_M rax, rcx, rdi + ret + +print_from_buf: ; word -> void + + PUSH_M rax, rsi, rdx, rdi ; сохраним регистры, которые точно попортим + mov rdx, rdi ; сколько выводить, в rdi содержится единственный аргумент + mov rsi, print_buf ; откуда выводить. Адрес буфера + mov rdi, STDOUT; куда выводить. Дескриптор файла. В нашем случае стандартного вывода + mov rax, 1 + RPOP_M rax, rsi, rdx, rdi + syscall + + RPOP_M rax, rsi, rdx, rdi ; вернем значения регистров + ret + +read_buf: ; none -> void. Пытается заполнить буфер из стандартного ввода + PUSH_M rax, rdi, rsi + mov rdi, STDIN ; откуда читать (дескриптор файла) + mov rsi, input_buf ; куда читать + mov rdx, input_size ; Сколько пытаемся читать + mov rax, 0 ; системный вызов чтения + RPOP_M rax, rdi, rsi + ret + +;poll_stdin: +; PUSH_M rdi, rsi, rdx +; mov rsi, 1 ; следим только за одним потоком +; +; RPOP_M rdi, rsi, rdx +; ret + + +_start: + mov rcx, src_size + mov rsi, src + mov rdi, print_buf + + xor rax, rax ; обнуляем регистр + .transfer: ; в цикле передаем данные, попутно конвертируя их в ascii + lodsb + DIGIT_TO_ASCII rax + stosb + loop .transfer + + mov [rdi + 1], BYTE `\n` ; Чтобы система не ругалась на отсутствие переноса + + mov rdi, src_size + call print_from_buf + +exit: + mov rax, 60 + mov rdi, 0 + syscall +