From 78a4638401c74e5e9c92caad296a434a0438b0d1 Mon Sep 17 00:00:00 2001 From: Miheev Egor Date: Tue, 24 Sep 2024 12:06:11 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=B2=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 03-asm-bios/task4.asm | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/03-asm-bios/task4.asm b/03-asm-bios/task4.asm index ed69cae..37d281d 100644 --- a/03-asm-bios/task4.asm +++ b/03-asm-bios/task4.asm @@ -79,7 +79,9 @@ print_from_buf: ; qword -> void; пытается вывести данные и mov rsi, print_buf ; откуда выводить. Адрес буфера mov rdi, STDOUT; куда выводить. Дескриптор файла. В нашем случае стандартного вывода mov rax, 1 + push rcx syscall + pop rcx RPOP_M rax, rsi, rdx, rdi ; вернем значения регистров ret @@ -114,26 +116,33 @@ print_number: ; qword (rdi) -> void ; создаем базу для адресации. Тогда первая будет на rbp - 8 - делитель, а вторая на rbp - 16 - количество mov rbp, rsp ; [WARNING] тут надо будет сохранить регистры - sub rsp, 16 ; выделяем место под 2 переменные - mov qword [rbp - 8], 10 ; пусть и жирно, но операнд обязан быть 64 разрядным для корректного деления - mov qword [rbp - 16], 0 ; счетчик + push rsp ; сохраню, потому что после всей вакханалии я концов не сыщу + sub rsp, 16 ; выделяем место под 3 переменные + mov qword [rbp - 16], 10 ; пусть и жирно, но операнд обязан быть 64 разрядным для корректного деления + mov qword [rbp - 24], 0 ; счетчик mov rax, rdi + push byte 0 ; при выводе он ориентируется на это как на конец строки .division_loop: xor rdx, rdx ; обнулим найденый остаток. (он просто еще и при делении принимает участие) - div qword [rbp - 8] + div qword [rbp - 16] DIGIT_TO_ASCII dl PUSHR8 dl ; поскольку в процессор не завезли возможность закинуть в стек 8 битный регистр, я им немного помог макросами - inc qword [rbp - 16] ; увеличиваем счетчик на единицу + inc qword [rbp - 24] ; увеличиваем счетчик на единицу test rax, rax ; делает and поразрядное с самим собой. Меня интересует, лежит ли в rax ноль jnz .division_loop ; если в rax не ноль, то продолжаем цикл ; выводим число mov rax, 1 mov rdi, STDOUT mov rsi, rsp - mov rdx, [rbp-16] - add rsp, 16 ; освобождаем память + mov rdx, [rbp-24] ; уже не надо очищать, потому что в конце я просто восстановлю как было + push rcx + syscall + pop rcx + + mov rsp, [rbp - 8] RPOP_M rdx, rdi, rsi pop rbp + ret _start: mov rbp, rsp @@ -156,6 +165,7 @@ _start: dec rcx mov rax, [rbp - 8] stosq + xor rax, rax inc word [rbp - 18] mov qword [rbp - 8], 0 test rcx, rcx @@ -171,25 +181,26 @@ _start: ASCII_TO_DIGIT al ; Если цифра, то конвертируем ее из ascii ; Поскольку умножение и деление можно сделать только через регистр, придется извратиться - PUSH_M ax, rdx + PUSH_M rax, rdx mov rax, [rbp - 8] mov qword [rbp - 16], 10 mul qword [rbp - 16] mov [rbp - 8], rax - RPOP_M ax, rdx + RPOP_M rax, rdx add [rbp - 8], rax ; результат деления запишем в локальную переменную loop .read_byte ; читаем буфер ввода до конца .check_buf: call poll_stdin - test BYTE [revents], POLLIN + test dword [revents], POLLIN jnz .read_loop ; Теперь выведем прочитанный массив на экран xor rcx, rcx mov cx, [rbp - 18] - .output_loop: mov rsi, array + call clean_print_buf + .output_loop: lodsq mov rdi, rax call print_number