From 49d3c02d7d5fe8a569cb61dfb9a28c96b46e2cc7 Mon Sep 17 00:00:00 2001 From: Miheev Egor Date: Sun, 22 Sep 2024 15:27:21 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20task2=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Решен второй пункт в виде ассемблерного кода, однако он отформатирован вполне определенным образом --- 03-asm-bios/task2.asm | 81 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 03-asm-bios/task2.asm diff --git a/03-asm-bios/task2.asm b/03-asm-bios/task2.asm new file mode 100644 index 0000000..579373a --- /dev/null +++ b/03-asm-bios/task2.asm @@ -0,0 +1,81 @@ +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 + +section .text + +%macro DIGIT_TO_ASCII 1 ; макрос, принимающий один регистр + add %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. Все, что не влезло, пушится в стек +; У передачи через стек тоже есть особенности, но их мы пока касаться не будем + +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 + syscall + + RPOP_M rax, rsi, rdx, rdi ; вернем значения регистров + 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 +